Основная проблема с вашим кодом заключается в том, что вы не обнуляете буфер, полученный из malloc()
, поэтому первый strcat()
не обязательно будет записываться в начале строки, но в конце .
Вы можете исправить это с помощью strcpy()
сразу после вызова malloc()
и проверить:
strcpy(ptr, "");
Или, что эквивалентно, вы можете просто установить первый байт буфера в нуль. Поскольку C строки являются строками с нулевым символом в конце, установка символа в ноль будет означать, что он в конце:
ptr[0] = 0;
Вы также, кажется, выделяете свой буфер слишком коротким. Если вы напишите n-1
копии Aa~
(4 байта) плюс одну копию Pa! Aa!
(8 байт, если вы добавите конечный ноль!), Вам на самом деле понадобится 4 * (n+1)
в качестве пробела. Так что либо всегда выделяйте это, либо делайте так в случае n < 6
, где вам нужны дополнительные байты.
Это также проблема:
ptr = "";
Потому что теперь ваш ptr
больше не указывает на буфер, возвращаемый malloc()
, но на stati c (пустую) строку в вашем двоичном файле. Вполне вероятно, что это то место, где у вас возникают проблемы с free()
, поскольку вызывать его для строки c в вашем двоичном коде определенно неверно.
Более того, после установки ptr = ""
у вас больше нет ссылок на выделенный вами буфер, что означает, что вы, скорее всего, только что создали утечку памяти!
В этом случае вам следует просто использовать strcpy()
или установить первый байт на ноль. Но если вы делаете это в начале программы, вам не нужно делать это здесь.
Наконец, free(NULL);
работает (как и не выдает ошибку), потому что это часть его спецификация, вы можете передать ему указатель NULL, и он ничего не будет делать. Но обратите внимание, что это не освобождает выделенный вами буфер, поэтому у вас здесь также есть утечка памяти.
Я бы еще больше реорганизовал вторую часть вашего кода, чтобы у вас не было слишком много повторений, добавляющих строки:
char *sc(int n) {
/* if n <= 6 then will have an extra "Aa!"
* after "Pa!" at the nth position.
*/
char *ptr;
if (n < 0) {
printf("Error!");
return NULL;
}
ptr = (char*) malloc(4 * (n+1));
if (ptr == NULL){
printf("malloc failed");
return NULL;
}
strcpy(ptr, "");
if (n > 1) {
for (int i = 1; i < n; i++){
strcat(ptr, "Aa~ ");
}
strcat(ptr, "Pa!");
if (n <= 6) {
strcat(ptr, " Ah!");
}
}
return ptr;
}
Также обратите внимание, что вам не нужно присваивать результат strcat()
обратно ptr
каждый раз, так как он всегда возвращает свой первый аргумент в любом случае, поэтому присвоение ему там ничего не меняет на самом деле.