Как исправить эту функцию, чтобы она возвращала конкатенацию двух строк?
Я пытаюсь написать пользовательскую функцию в C, которая объединит две строки. До сих пор я придумал:
char *strcat406(char *str1, char *str2) {
int str1length = 0;
int str2length = 0;
char newStr[str1length + str2length];
int i;
for (i = 0; i < str1[i] != '\0'; i++)
str1length += 1;
for (i = 0; i < str2[i] != '\0'; i++)
str2length += 1;
for (i = 0; i < str1[i] != '\0'; i++)
newStr[i] = str1[i];
for (i = i; i < str2[i] != '\0'; i++)
newStr[i] = str2[i];
return newStr;
}
Я считаю, что код должен работать, за исключением строки, которая читает return newStr;
XCode дает мне ошибку, которая гласит "адрес стековой памяти, связанной с возвращенной локальной переменной (x)", и я думаю, именно поэтому я не получаю массив строк, напечатанный в main, как я хочу.
Из моих исследований кажется, что это происходит потому, что память для возвращенного массива освобождается, и поэтому я получаю результат, который мне не нужен, хотя я не нашел ни одного ответа на этом сайте или даже в документации C, которая имеет работал на меня.
Как я могу изменить свою функцию, чтобы она возвращала объединение двух строк?
2 ответа
Вы должны вычислить длину полученной строки, затем выделить для нее память, затем скопировать ее и вернуть. Вы сейчас используете VLA. Лучше использовать malloc:
char *strcat406(char *str1, char *str2) {
int str1length = 0;
int str2length = 0;
char *newStr; // note: length not known yet
int i, j;
for (i = 0; i < str1[i] != '\0'; i++)
str1length += 1;
for (i = 0; i < str2[i] != '\0'; i++)
str2length += 1;
newstr= malloc (str1length + str2length + 1);
for (i = 0; str1[i] != '\0'; i++)
newStr[i] = str1[i];
for (j = 0 ;str2[j] != '\0'; j++)
newStr[i+j] = str2[j];
newstr[i+j]= '\0';
return newStr;
}
Есть лучшие способы сделать это, но я придерживаюсь вашего подхода. Не забудьте позвонить бесплатно для новой строки, когда она вам больше не нужна.
РЕДАКТИРОВАТЬ Лучший подход:
char *strcat406(char *str1, char *str2)
{
char *newStr= malloc(strlen(str1)+strlen(str2)+1);
strcpy(newStr,str1);
strcat(newStr,str2);
return newStr;
}
Две вещи, чтобы сказать
- Не полагайтесь на VLA, так как они сделаны в качестве дополнительной детали стандарта C11.
- VLA не должны быть размещены в памяти кучи, по крайней мере, стандарт ничего не предписывает.
Простое решение: (Я не проверял логику конкатенации)
Делать newStr
указатель и использовать динамическое выделение памяти [ malloc()
/ calloc()
].
Динамически распределенная память остается в области действия до тех пор, пока она не будет распределена программно, поэтому они не ограничены областью действия функции, в которой они определены. В функции вызова вы должны освободить память после того, как с ней покончено.