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;
}