gpt4 book ai didi

c - 无效写入——Valgrind

转载 作者:太空宇宙 更新时间:2023-11-03 23:53:39 25 4
gpt4 key购买 nike

您好,我在我的 C 程序中遇到了 munmap_chunk():无效指针:错误。

主要的问题是……我什至不确定指针可以通过哪些方式变为无效。我检查了我的所有代码,看是否没有使用足够的空间调用字符串,但没有发现任何看起来会越界的东西!

相关代码如下(反正我觉得是相关代码)

//Takes in a username and suggests friends of friends who are the opposite sex as friends of username
395 void suggest_friends(char* username, FILE* out) {
396 //printf("ENTER suggest_friends\n");
397 to_lowercase(username);
398
399 if (check_username(username) == 0) {
400
401 struct user_node *user = search_username(username);
402 if (user != NULL) {
403
404 struct friend_node *a_friend = user->a_friend;
405 struct friend_node *friends_friend = NULL;
406 struct friend_node *temp_friends_friend = NULL;
407
408 struct friend_suggest_node *list = NULL;
409 struct friend_suggest_node *list_it = NULL;
410 struct friend_suggest_node *new_suggest = NULL;
411 int friend_suggest_switch = -1;
412
413 int print_string_size = 50;
414 int print_string_len = 0;
415 char* print_string = calloc(print_string_size + 1, sizeof(char));
416 char* user_string = NULL;
417 int num_suggestions = 0;
418 int num_mutual_friends = 0;
419 int max_friends = 0;
420
421 //Iterate over all friends
422 while (a_friend != NULL) {
423
424 friends_friend = a_friend->user->a_friend;
425 //Does friend have friends of opposite sex that I'm not friends with?
426 //Iterate over friend's friends
427 while (friends_friend != NULL) {
428
429 num_mutual_friends = 0;
430 //mutual friend found
431 //Different gender, and not friends
432 if (friends_friend->user->gender != user->gender && are_friends(friends_friend->u ........ser, user) != 0) {
433
434 //are there are elements in the suggested friends list yet??
435 if (list == NULL) {
436
437 new_suggest = malloc(sizeof(struct friend_suggest_node));
438 new_suggest->user = friends_friend->user;
439 new_suggest->next = NULL;
440 list = new_suggest;
441 friend_suggest_switch = 0;
442 }
443 //there are already elements
444 else {
445
446 friend_suggest_switch = 0;
447 //Loop over suggested friends, to check if friends friend already found
448 list_it = list;
449 while (list_it != NULL) {
450
451 //if the user is already in the suggested list
452 if (list_it->user == friends_friend->user) {
453 friend_suggest_switch = -1;
454 break;
455 }
456 list_it = list_it->next;
457 }
458
459 //if the friend to suggest is a new suggestion
460 if (friend_suggest_switch == 0) {
461
462 //add friend to suggest to the front of the list
462 //add friend to suggest to the front of the list
463 new_suggest = malloc(sizeof(struct friend_suggest_node));
464 new_suggest->user = friends_friend->user;
465 new_suggest->next = list;
466 list = new_suggest;
467 }
468 }
469
470 //if the friend found was new
471 if (friend_suggest_switch == 0) {
472
473 //INTENTION? LOOP OF THE FRIEND OF A FRIEND'S FRIEND LIST!?
474 //Loop over the remainder of the user's friends's, friend list
475 //whom is about to be suggested as a mutual friend
476 temp_friends_friend = friends_friend->user->a_friend;
477 while (temp_friends_friend != NULL) {
478
479 //if user is found who is a mutual friend with user
480 if (are_friends(temp_friends_friend->user, user) == 0) {
481
482 num_mutual_friends++;
483 }
484
485 temp_friends_friend = temp_friends_friend->next_friend;
486 }
487
488 //if more mutual friends then previous choice,
489 //set user_string equal to this user now
490 if (num_mutual_friends > max_friends) {
491 max_friends = num_mutual_friends;
492 }
493
494 //get string for user
495 user_string = get_user_string(friends_friend->user);
496 num_suggestions++;
497 //+3 for \0 and ', '
498 print_string_len = strlen(user_string) + 3;
498 print_string_len = strlen(user_string) + 3;
499
500 //if length exceeds size of string
501 if (print_string_len > print_string_size) {
502
503 while (print_string_len >= print_string_size) {
504 print_string_size *= 2;
505 }
506
507 char* temp_string = calloc(print_string_size + 1, sizeof(char));
508 strcpy(temp_string, print_string);
509 free(print_string);
510 print_string = temp_string;
511 temp_string = NULL;
512 }
513
514 //add ", " fot string for formatting
515 if (strlen(print_string) > 0) {
516 strcat(print_string, ", \0");
517 //TBR
518 //printf("AFTER TACKING ON COMMA!\n");
519 }
520 strcat(print_string, user_string);
521 //TBR
522 //fprintf(out, "before fail 111\n");
523 //fprintf(out, "user_string is %s\n", user_string);
524 //fprintf(out, "user_string ptr is %p\n", user_string);
525 free(user_string);
526 //TBR
527 //fprintf(out, "after fail 111???\n");
528 user_string = NULL;
529 }
530 }
531
532 friends_friend = friends_friend->next_friend;
533 }
534
535 a_friend = a_friend->next_friend;
536 }
537
538 if (num_suggestions != 0) {
539 fprintf(out, "%s may know following people because they have %d mutual friend(s):\n%s ........\n", username, max_friends, print_string);
540 }
541 else {
542 fprintf(out, "Sorry, there are no friend suggestions for %s.\n", username);
543 }
544
545 free(print_string);
546 print_string = NULL;
547 }
548 else {
549 fprintf(out, "User %s does not exist. Please try again.\n", username);
550 }
551 }
552 else {
553 fprintf(out, "%s username is not a valid username\n", username);
554 }
555 //printf("EXIT suggest_friends\n");
556 }



//Takes a user_node and returns a char* to a string holding the user's info
771 //in the format name/age/gender/location
772 char* get_user_string(struct user_node *user) {
773 char age[5];
774 sprintf(age, "%d", (user->age));
775 char* gender = NULL;
776
777 //Female
778 if (user->gender == 0) {
779 gender = "female\0";
780 }
781 //male
782 else {
783 gender = "male\0";
784 }
785
786 //allocate memory for length of location, name, age, and gender + 3 '/'s + \0
787 //+20 for good measure!!!
788 char* user_string = NULL;
789 user_string = calloc((strlen(user->name) + strlen(user->location) + strlen(age) + strlen(gender) ........+ 4 + 20), sizeof(char));
790 strcat(user_string, user->name);
791 strcat(user_string, "/");
792 strcat(user_string, age);
793 strcat(user_string, "/");
794 strcat(user_string, gender);
795 strcat(user_string, "/");
796 strcat(user_string, user->location);
797 return user_string;
798 }

当我通过 valgrind 运行它时,我得到了这个输出:

==10158== Memcheck, a memory error detector
==10158== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==10158== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==10158== Command: ./social_network -f crash_tester.txt crash_test_output.txt
==10158==
==10158== Invalid write of size 1
==10158== at 0x402C36B: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10158== by 0x804A434: suggest_friends (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== Address 0x41f12bb is 0 bytes after a block of size 51 alloc'd
==10158== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10158== by 0x804A1F3: suggest_friends (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158==
==10158== Invalid write of size 1
==10158== at 0x402C390: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10158== by 0x804A434: suggest_friends (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== Address 0x41f12cf is not stack'd, malloc'd or (recently) free'd
==10158==
==10158== Invalid read of size 1
==10158== at 0x4089E29: vfprintf (vfprintf.c:1630)
==10158== by 0x4091EBE: fprintf (fprintf.c:33)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== Address 0x41f12bb is 0 bytes after a block of size 51 alloc'd
==10158== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10158== by 0x804A1F3: suggest_friends (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158==
==10158== Invalid read of size 4
==10158== at 0x40C40BC: __GI_mempcpy (mempcpy.S:60)
==10158== by 0x40B6769: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1350)
==10158== by 0x4089E01: vfprintf (vfprintf.c:1630)
==10158== by 0x4091EBE: fprintf (fprintf.c:33)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== Address 0x41f12bb is 0 bytes after a block of size 51 alloc'd
==10158== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10158== by 0x804A1F3: suggest_friends (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804B25A: command_read (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049460: read_args_file (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x8049294: switch_parsing (in /home/ethan/cs2506/comp-org-3/social_network)
==10158== by 0x804ACF7: main (in /home/ethan/cs2506/comp-org-3/social_network)
==10158==

最佳答案

我认为问题出在这里:

print_string_len = strlen(user_string) + 3;

//if length exceeds size of string
if (print_string_len > print_string_size) {

while (print_string_len >= print_string_size) {
print_string_size *= 2;
}

char* temp_string = calloc(print_string_size + 1, sizeof(char));
strcpy(temp_string, print_string);
free(print_string);
print_string = temp_string;
temp_string = NULL;
}

//add ", " fot string for formatting
if (strlen(print_string) > 0) {
strcat(print_string, ", \0");
}
strcat(print_string, user_string);

当您尝试根据缓冲区限制预先检查最终结果长度时,最终结果长度计算不正确。您忘记包含缓冲区的预先存在的内容;例如strlen(print_string).

所以我认为你需要改变:

print_string_len = strlen(user_string) + 3;

到:

print_string_len = strlen(print_string) + strlen(user_string) + 3;

关于c - 无效写入——Valgrind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13635084/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com