本文介绍了无效写入-Valgrind的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 14:30