C 直接使用字符数组分配结构是否安全?

C 直接使用字符数组分配结构是否安全?,c,C,我有一个结构: struct test { int a; char b[20]; }; struct test x; struct test *y = malloc(sizeof(*y)); y->a = 3; memcpy(y->b, "aaaa", 4); 然后如果我赋值x=*y 免费(y) 安全吗?作业是否从y->b复制到x->b?或者只是将x->b指向y->b的内存区域 我进行了测试,似乎没有出现任何问题。正如@WhozCraig在评论中提到的那样,它是安全的,您

我有一个结构:

struct test {
  int a;
  char b[20];
};

struct test x;
struct test *y = malloc(sizeof(*y));
y->a = 3;
memcpy(y->b, "aaaa", 4);
然后如果我赋值
x=*y

免费(y)

安全吗?作业是否从
y->b
复制到
x->b
?或者只是将
x->b
指向
y->b
的内存区域


我进行了测试,似乎没有出现任何问题。

正如@WhozCraig在评论中提到的那样,它是安全的,您正在
x
中复制
y
的内容(因此当
y
发生变化时
x
不会)

与您的问题无关,但我想说,当您使用
memcpy
时,如果您想将完整字符串复制到另一个字符串中,则应使用
字符串长度+1
(要复制
\0
)。例如,在您的代码中,
y->b
未终止

这里也应该是
struct test*y=malloc(sizeof(*y))此:

结构测试*y=malloc(sizeof(y))


要为结构分配内存(不是指针)

也正如注释中提到的@WhozCraig,它是安全的,并且您正在
x
中复制
*y
的内容(因此当
y
更改
x
时不会)

与您的问题无关,但我想说,当您使用
memcpy
时,如果您想将完整字符串复制到另一个字符串中,则应使用
字符串长度+1
(要复制
\0
)。例如,在您的代码中,
y->b
未终止

这里也应该是
struct test*y=malloc(sizeof(*y))此:

结构测试*y=malloc(sizeof(y))


为结构分配内存。(不是指针)

是的,您可以这样安全地进行赋值(它是逐位复制)

#包括
#包括
结构测试
{
INTA;
charb[20];
};
int main()
{
结构测试ob1、ob2;
ob1.a=1;
strcpy(ob1.b,“abc”);
ob2=ob1;
printf(“%c\n%s”,ob2.a,ob2.b);
返回0;
}
但见下文

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct test
{
  char *ptr;
};


int main()
{
    struct test ob1,ob2;

    ob1.ptr=malloc(sizeof(char)*10);
    ob2.ptr=malloc(sizeof(char)*10);

    if(ob1.ptr==NULL||ob2.ptr==NULL)
    {
        if(ob1.prt!=NULL)
            free(ob1.ptr);
        if(ob2.ptr!=NULL)
            free(ob2.ptr);

        exit(1);
    }    

    strcpy(ob1.ptr,"abc");
    ob2=ob1;
    strcpy(ob2.ptr,"def");

    printf("%s",ob1.ptr);

    free(ob1.ptr);
    free(ob2.ptr);

    return 0;
}
#包括
#包括
#包括
结构测试
{
char*ptr;
};
int main()
{
结构测试ob1、ob2;
ob1.ptr=malloc(sizeof(char)*10);
ob2.ptr=malloc(sizeof(char)*10);
if(ob1.ptr==NULL | | ob2.ptr==NULL)
{
如果(ob1.prt!=NULL)
免费(ob1.ptr);
if(ob2.ptr!=NULL)
免费(ob2.ptr);
出口(1);
}    
strcpy(ob1.ptr,“abc”);
ob2=ob1;
strcpy(ob2.ptr,“def”);
printf(“%s”,ob1.ptr);
免费(ob1.ptr);
免费(ob2.ptr);
返回0;
}
这段代码打印“def”,导致内存泄漏,并再次释放相同的内存,所以如果您的结构包含您负责的指针,您可以执行以下操作

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct test
{
  char *ptr;
};

void testcopy(struct test* ob1,struct test* ob2)
{
   strcpy(ob1->ptr,ob2->ptr);
}

int main()
{
    struct test ob1,ob2;

    ob1.ptr=malloc(sizeof(char)*10);
    ob2.ptr=malloc(sizeof(char)*10);

    if(ob1.ptr==NULL||ob2.ptr==NULL)
    {
        if(ob1.prt!=NULL)
            free(ob1.ptr);
        if(ob2.ptr!=NULL)
            free(ob2.ptr);

        exit(1);
    }  

    strcpy(ob1.ptr,"abc");
    testcopy(&ob2,&ob1);
    strcpy(ob2.ptr,"def");

    printf("%s",ob1.ptr);
    printf("\n%s",ob2.ptr);

    free(ob1.ptr);
    free(ob2.ptr);

    return 0;
}
#包括
#包括
#包括
结构测试
{
char*ptr;
};
无效测试副本(结构测试*ob1,结构测试*ob2)
{
strcpy(ob1->ptr,ob2->ptr);
}
int main()
{
结构测试ob1、ob2;
ob1.ptr=malloc(sizeof(char)*10);
ob2.ptr=malloc(sizeof(char)*10);
if(ob1.ptr==NULL | | ob2.ptr==NULL)
{
如果(ob1.prt!=NULL)
免费(ob1.ptr);
if(ob2.ptr!=NULL)
免费(ob2.ptr);
出口(1);
}  
strcpy(ob1.ptr,“abc”);
测试副本(&ob2和&ob1);
strcpy(ob2.ptr,“def”);
printf(“%s”,ob1.ptr);
printf(“\n%s”,ob2.ptr);
免费(ob1.ptr);
免费(ob2.ptr);
返回0;
}

是的,你可以这样做是安全的(它是一点一点拷贝)

#包括
#包括
结构测试
{
INTA;
charb[20];
};
int main()
{
结构测试ob1、ob2;
ob1.a=1;
strcpy(ob1.b,“abc”);
ob2=ob1;
printf(“%c\n%s”,ob2.a,ob2.b);
返回0;
}
但见下文

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct test
{
  char *ptr;
};


int main()
{
    struct test ob1,ob2;

    ob1.ptr=malloc(sizeof(char)*10);
    ob2.ptr=malloc(sizeof(char)*10);

    if(ob1.ptr==NULL||ob2.ptr==NULL)
    {
        if(ob1.prt!=NULL)
            free(ob1.ptr);
        if(ob2.ptr!=NULL)
            free(ob2.ptr);

        exit(1);
    }    

    strcpy(ob1.ptr,"abc");
    ob2=ob1;
    strcpy(ob2.ptr,"def");

    printf("%s",ob1.ptr);

    free(ob1.ptr);
    free(ob2.ptr);

    return 0;
}
#包括
#包括
#包括
结构测试
{
char*ptr;
};
int main()
{
结构测试ob1、ob2;
ob1.ptr=malloc(sizeof(char)*10);
ob2.ptr=malloc(sizeof(char)*10);
if(ob1.ptr==NULL | | ob2.ptr==NULL)
{
如果(ob1.prt!=NULL)
免费(ob1.ptr);
if(ob2.ptr!=NULL)
免费(ob2.ptr);
出口(1);
}    
strcpy(ob1.ptr,“abc”);
ob2=ob1;
strcpy(ob2.ptr,“def”);
printf(“%s”,ob1.ptr);
免费(ob1.ptr);
免费(ob2.ptr);
返回0;
}
这段代码打印“def”,导致内存泄漏,并再次释放相同的内存,所以如果您的结构包含您负责的指针,您可以执行以下操作

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct test
{
  char *ptr;
};

void testcopy(struct test* ob1,struct test* ob2)
{
   strcpy(ob1->ptr,ob2->ptr);
}

int main()
{
    struct test ob1,ob2;

    ob1.ptr=malloc(sizeof(char)*10);
    ob2.ptr=malloc(sizeof(char)*10);

    if(ob1.ptr==NULL||ob2.ptr==NULL)
    {
        if(ob1.prt!=NULL)
            free(ob1.ptr);
        if(ob2.ptr!=NULL)
            free(ob2.ptr);

        exit(1);
    }  

    strcpy(ob1.ptr,"abc");
    testcopy(&ob2,&ob1);
    strcpy(ob2.ptr,"def");

    printf("%s",ob1.ptr);
    printf("\n%s",ob2.ptr);

    free(ob1.ptr);
    free(ob2.ptr);

    return 0;
}
#包括
#包括
#包括
结构测试
{
char*ptr;
};
无效测试副本(结构测试*ob1,结构测试*ob2)
{
strcpy(ob1->ptr,ob2->ptr);
}
int main()
{
结构测试ob1、ob2;
ob1.ptr=malloc(sizeof(char)*10);
ob2.ptr=malloc(sizeof(char)*10);
if(ob1.ptr==NULL | | ob2.ptr==NULL)
{
如果(ob1.prt!=NULL)
免费(ob1.ptr);
if(ob2.ptr!=NULL)
免费(ob2.ptr);
出口(1);
}  
strcpy(ob1.ptr,“abc”);
测试副本(&ob2和&ob1);
strcpy(ob2.ptr,“def”);
printf(“%s”,ob1.ptr);
printf(“\n%s”,ob2.ptr);
免费(ob1.ptr);
免费(ob2.ptr);
返回0;
}

是的,很安全。这与没有动态分配没有什么不同。它是结构复制,复制成员。事实上,从函数结果返回固定长度的数组通常会利用该语言特性,将固定数组埋在结构中,然后将结构作为函数结果返回。如果
b
是动态的,这将是有问题的,但实际上没有问题
不会复制字符串文本末尾的空终止符。是的,这是安全的。这与没有动态分配没有什么不同。它是结构复制,复制成员。事实上,从函数结果返回固定长度的数组通常会利用该语言特性,将固定数组埋在结构中,然后将结构作为函数结果返回。如果
b
是动态的,这将是有问题的,但实际上没有问题
不会复制字符串文字结尾处的null终止符。