问题描述
我遇到了munmap_chunk():无效的指针:我的c程序出错.
Hi I'm running into an munmap_chunk(): invalid pointer: error in my c program.
主要问题是...我什至不确定指针变为无效的所有方式.我已经检查了我的代码中是否没有足够的空间来调用字符串,但是没有发现看起来会超出范围的内容!
The main problem is...I'm not even sure what all of the ways a pointer can become invalid are. I've checked all over my code for strings not being calloced with enough space, but found nothing that looks like it'll run over bounds!
下面是相关代码(无论如何,我认为是相关代码)
The relevant code is below (what I THINK is the relevant code anyway)
//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运行它时,得到以下输出:
When I run it through valgrind I get this output:
==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)
.
While you attempt to pre-check the end result length against your buffer limit, the end result length is not calculated correctly. You are forgetting to include the pre-existing contents of the buffer; e.g. strlen(print_string)
.
所以我认为您需要更改:
So I think you need to change:
print_string_len = strlen(user_string) + 3;
收件人:
print_string_len = strlen(print_string) + strlen(user_string) + 3;
这篇关于无效写入-Valgrind的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!