以下是程序的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * cloning(char * q){
char s[strlen(q)];
int i;
for(i = 0; i < strlen(q); i++)
s[i] = q[i];
return s;
}
int main(){
char q[] = "hello";
char *s = cloning(q);
return 0;
}
编译后出现警告,所以我更改了返回的值:
char *b = s;
return b;
通过这种方式可以解决警告问题。但是我发现在函数cloning()中,sizeof(s)是5,但是strlen(s)是7.如果我将char s [strlen(q)]简单地改为char s [5],输出仍然是不正确。有人可以向我解释这个问题吗?非常感谢你。
答案 0 :(得分:6)
char s[strlen(q)]
是一个局部变量,因此当您返回其地址时,会导致未定义的行为。因此,您可以使用strdup()
或malloc()
来动态分配数组,从而确保从函数返回时堆上的数组可用。返回的数组也需要free()
- ed,否则会有内存泄漏:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * cloning(char * q){
char *s = malloc(strlen(q)+1);
// if you write char s[strlen(q)], it is defined locally, and thus on return gives an undefined behaviour
int i;
for(i = 0; i < strlen(q)+1; i++)
s[i] = q[i];
return s;
}
int main(){
char q[] = "hello";
char *s = cloning(q);
free(s);
return 0;
}
答案 1 :(得分:3)
char s[strlen(q)];
是一个可变长度数组。像malloc的缓冲区一样,它的大小在运行时确定。与malloc的缓冲区不同,它在函数返回时不再存在。
答案 2 :(得分:3)
此代码存在多个问题:
char * cloning(char * q){
char s[strlen(q)]; // s has strlen size but needs strlen + 1 to hold \0
int i;
for(i = 0; i < strlen(q); i++) // should copy the \0 otherwise q is not a valid string
s[i] = q[i];
return s;// returns the address of a local var == undef. behavior
}
如果要克隆字符串,请执行strdup()
char* cloning(char* q)
{
return strdup(q);
}
或等效的
char * cloning(char * q)
{
char* s = malloc(strlen(q)+1);
int i;
for(i = 0; i < strlen(q)+1; i++)
s[i] = q[i];
return s;
}
答案 3 :(得分:2)
使用标准C执行此操作的正确方法,无论C标准的版本如何,都是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* cloning (const char* str)
{
char* clone;
size_t size = strlen(str) + 1;
clone = malloc(size);
if(clone == NULL)
{
return NULL;
}
memcpy(clone, str, size);
return clone;
}
int main(){
char original[] = "hello";
char* clone = cloning(original);
if(clone == NULL)
{
puts("Heap allocation failed.");
return 0;
}
puts(clone);
free(clone);
return 0;
}
答案 4 :(得分:0)
C中的动态数组使用Malloc和Calloc声明。尝试谷歌搜索。
例如:
char *test;
test = (char *)malloc(sizeof(char)*Multiply_By);
答案 5 :(得分:-1)
在C中,静态数组在堆栈中,在函数返回后,它已被破坏。和带有char的字符串有一个'\ 0'结尾。但是strlen不包含它。例如。char q[] = "hello"; strlen(q) = 5,but the real size is 6
如果要复制字符串,则必须在结尾添加最后一个'\ 0'。使用
char *s = malloc(sizeof(q)); ...; for(i = 0; i < sizeof(q); i++)
s[i] = q[i];
使用后你也需要释放它。可能会成为一个内存泄漏。
希望这可以帮到你。