освобождая результаты в аварии - PullRequest
0 голосов
/ 07 июня 2019

В чем разница между:

Case1:

    char* strings[100];
    strings[0]=malloc(100);
    char str[100]="AAA";
    strings[0]=strdup(str);
    free(strings[0]);

Case2:

    char* strings[100];
    strings[0]=malloc(100);
    strings[0]="AAA";
    free(strings[0]);

Case2приводит к аварии.strdup равен malloc, за которым следует strcpy.Почему сбой второго случая?

Ответы [ 3 ]

4 голосов
/ 07 июня 2019

strings[0]="AAA"; не копирует содержимое AAA в память, на которую указывает string[0], скорее позволяет strings[0] указывать на строковый литерал "AAAA";и освобождение строкового литерала - неопределенное поведение, так как вы освобождаете память, которая не была выделена ранее через malloc.Обратите внимание, что вы потеряли любой доступ к ранее malloc редактируемой памяти после выполнения оператора strings[0]="AAA".

Чтобы скопировать содержимое в malloc ed память, напишите strcpy(strings[0],"AAA").Тогда у free больше не должно быть проблем.

2 голосов
/ 07 июня 2019

Это может произойти сбой просто потому, что именно это (как правило, поведение не определено) происходит, когда вы пытаетесь освободить указатель, который не указывает на память, которая может быть освобождена.Подробнее о строковых литералах читайте здесь: https://stackoverflow.com/a/1704433/6699433

И оба ваших примера написаны очень плохо, поскольку malloc просто никогда не используется.

char* strings[100];
strings[0]=malloc(100);
char str[100]="AAA";
strings[0]=strdup(str);
free(strings[0]); 

эквивалентно

char* strings[100];
char str[100]="AAA";
strings[0]=strdup(str);
free(strings[0]);

и

char* strings[100];
strings[0]=malloc(100);
strings[0]="AAA";
free(strings[0]);

эквивалентны

char* strings[100];
strings[0]="AAA";
free(strings[0]);

Обратите внимание, что «эквивалент» не на 100% корректен, поскольку у вас есть побочные эффекты.Я просто хотел показать, что некоторые строки абсолютно бессмысленны, так как вы не используете результат перед переназначением переменных.

1 голос
/ 07 июня 2019
strings[0]=malloc(100);

Здесь strings[0] - указатель на вновь выделенную память. Затем, однако, вы делаете strings[0]="AAA";, что заставляет его указывать на "AAA", строку в постоянной памяти. Ваша выделенная память теперь просочилась. Затем вы пытаетесь освободить "AAA", что вы не можете сделать, потому что это только для чтения памяти.

В первом фрагменте это работает, потому что вы освобождаете дублированную память, но вы все еще теряете выделенную память malloc.

...