C 动态和静态字符数组
以下是一个程序的代码:C 动态和静态字符数组,c,arrays,string,C,Arrays,String,以下是一个程序的代码: #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[]
#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;
}
这样就可以解决警告问题。但是我发现在函数cloning()中,sizeof(s)是5,而strlen(s)是7。如果我将char s[strlen(q)]简单地更改为char s[5],输出仍然是不正确的。谁能给我解释一下这个问题吗?非常感谢。C中的动态数组是使用Malloc和Calloc声明的。试着用谷歌搜索一下 例如:
C中的动态数组是使用Malloc和Calloc声明的。试着用谷歌搜索一下 例如:
char s[strlen(q)]
是一个局部变量,因此当您返回其地址时,它会导致未定义的行为。因此,您可以使用strdup()
或malloc()
动态分配数组,从而确保从函数返回时,堆上的数组s可用。返回的数组也需要空闲()
#包括
#包括
#包括
char*克隆(char*q){
char*s=malloc(strlen(q)+1);
//如果您写入字符s[strlen(q)],它是在本地定义的,因此在返回时会给出一个未定义的行为
int i;
对于(i=0;i
char s[strlen(q)]
是一个局部变量,因此当您返回其地址时,它会导致未定义的行为。因此,您可以使用strdup()
或malloc()
动态分配数组,从而确保从函数返回时,堆上的数组s可用。返回的数组也需要空闲()
#包括
#包括
#包括
char*克隆(char*q){
char*s=malloc(strlen(q)+1);
//如果您写入字符s[strlen(q)],它是在本地定义的,因此在返回时会给出一个未定义的行为
int i;
对于(i=0;i
是一个可变长度数组。与malloc'ed缓冲区一样,它的大小是在运行时确定的。与malloc'ed缓冲区不同,它在函数返回时停止存在
是一个可变长度数组。与malloc'ed缓冲区一样,它的大小是在运行时确定的。与malloc'ed缓冲区不同,它在函数返回时不再存在。在C中,静态数组在堆栈中,函数返回后,它被破坏。带有char的字符串有一个'\0'结尾。但是斯特伦没有包括在内。例如。charq[]=“你好”;strlen(q)=5,但实际大小为6
如果要复制字符串,必须在末尾添加最后一个“\0”。或使用
char*s=malloc(sizeof(q))。。。;对于(i=0;i
你还需要在使用后释放它。可能会成为内存泄漏
希望这能对你有所帮助。在C中,静态数组在堆栈中,函数返回后,它被销毁了。带有char的字符串有一个'\0'结尾。但是斯特伦没有包括在内。例如。charq[]=“你好”;strlen(q)=5,但实际大小为6
如果要复制字符串,必须在末尾添加最后一个“\0”。或使用
char*s=malloc(sizeof(q))。。。;对于(i=0;i
你还需要在使用后释放它。可能会成为内存泄漏
希望这可以帮助您解决此代码的多个问题:
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
}
或同等品
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;
}
char*克隆(char*q)
{
char*s=malloc(strlen(q)+1);
int i;
对于(i=0;i
此代码存在多个问题:
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
}
或同等品
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;
}
char*克隆(char*q)
{
char*s=malloc(strlen(q)+1);
int i;
对于(i=0;i
使用标准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;
}
#包括
#包括
#包括
字符*克隆(常量字符*字符串)
{
字符*克隆;
大小=strlen(str)+1;
克隆=malloc(大小);
如果(克隆==NULL)
{
返回NULL;
}
memcpy(克隆、str、大小);
返回克隆;
}
int main(){
char original[]=“你好”;
char*clone=克隆(原始);
如果(克隆==NULL)
{
puts(“堆分配失败”);
返回0;
}
放(克隆);
自由(克隆);
返回0;
}
使用标准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;
}
#包括
#包括
#包括
字符*克隆(常量字符*字符串)
{
字符*克隆;
大小=strlen(str)+1;
克隆=malloc(大小);
如果(克隆==NULL)
{
返回NULL;
}
memcpy(克隆、str、大小);
返回克隆;
}
int main(){
char original[]=“你好”;
char*clone=克隆(原始);
如果(克隆==NULL)
{
puts(“堆分配失败”);
返回0;
}
放(克隆);
自由(克隆);
返回0;
}
chars[strlen(q)]
是有效的C99可变长度数组;这不是未定义的行为。然而,无效的是返回一个指向它的指针,因为它具有自动存储持续时间。OP没有指定他是否在C99上操作,所以我取得了一些艺术许可证,可以说:)但感谢这一点。我编辑了答案,以释放malloc()-ed数组:)如果我们假设他们使用的是C89而不是C99,那么VLA的使用将是一个编译时错误。在你有机会调用未定义的行为之前,它就会被编译器捕获。啊,是的。我忘了!在这一点上,我编辑了我的答案,将Wumpus Q.Wumbley的观点也包括在内:)@CrazyHenry:编译器通过查看数组的定义来计算sizeof
<另一方面,code>strlen
,将在通过它的数组中搜索第一个N
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;
}
#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;
}