Освобождение malloc не удалит данные char - PullRequest
0 голосов
/ 06 ноября 2011

Я сделал меньший сценарий моей большой проблемы. Я пытаюсь передать строку функции, которая из нее создаст новую строку. Однако я столкнулся с некоторыми проблемами.

Я определил строку как

typedef char string[1024];

Тогда у меня есть функция, которая берет строку и создает новую строку, которая заполняется старой строкой и точечным символом

string* add_sth_to_string(char* msg){
    string* newStr=malloc(sizeof(string)); // malloc a newStr
    strcpy(*newStr, msg);            // copying msg to newStr

    char buff[1024];                 // making a buffer
    strcat(buff, ".");               // adding a dot to buffer
    strcat(buff, *newStr);           // adding msg   to buffer
    strcpy(*newStr, buff);           // copying buffer to newStr
    return newStr;
}

Затем в основном я пытаюсь использовать эту функцию 3 раза для новой строки каждый раз:

for (i=0; i<3; i++){
    string* newStr;
    newStr=add_sth_to_string("test");
    printf("str: %s\n", *newStr);
    free(newStr);
    // can even printf here
}

Это странный вывод, который я получаю:

str: .test
str: .test.test
str: .test.test.test

Когда я ожидаю получить:

str: .test
str: .test
str: .test

Кто-нибудь, кто может указать на то, что происходит? Что-то еще, что я нахожу странным, это то, что я могу напечатать значение newStr сразу после того, как освобождается .

Ответы [ 4 ]

7 голосов
/ 06 ноября 2011

Вы используете buff без инициализации. Попробуйте:

char buff[1024];
buff[0] = 0;

Что-то еще, что я нахожу странным, это то, что я могу напечатать значение newStr только после того, как я освободил это.

Доступ к памяти после освобождения - неопределенное поведение . Как правило, из соображений производительности free не обнуляет память.

Это 2 случая неопределенного поведения в одном и том же вопросе + один действительно странный typedef. Так держать!

3 голосов
/ 06 ноября 2011

Попробуйте изменить

strcat(buff, "."); 

в

strcpy(buff, "."); 

Или поочередно инициализировать buff при объявлении его следующим образом:

 char buff[1024] = "";
1 голос
/ 06 ноября 2011
string* newStr=malloc(sizeof(string)); // malloc a newStr
strcpy(*newStr, msg);            // copying msg to newStr

Это также приведет к сбою.string - указатель, поэтому sizeof возвращает 4 или 8, а не то, что вы хотели сделать.

Хорошо, забудьте о моем замечании, вы сделали typedef, но я позволю его показать здесьВы, почему typedef - плохая идея.На первый взгляд это запутало тот факт, что это был массив, а не указатель, для 30-строчной программы это не проблема, но когда вам нужно поддерживать проект на 200 000 строк (как я), вы начнете ненавидеть этитакие вещи.

Еще один момент, вам следует избегать работы со строками фиксированного размера по 1024 байта.1024 не такой большой (даже у домашнего компьютера 80-х годов были экраны больше этого), и для большинства, если строки довольно короткие, вы напрасно портите много памяти.

1 голос
/ 06 ноября 2011

Вы должны очистить содержимое buf[1024] каждой итерации.


UPDATE

Поскольку buf[1024] не будет автоматически обнуляться при размещении в стеке. И вы выбираете strcat для объединения двух строк, которые найдут \0 -конец. Таким образом, если buf содержит какое-то значение по умолчанию, это приведет к запутанному выводу.

Используйте buf[1024] = ""; для выделения буфера, чтобы исправить вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...