是否使用strcpy

是否使用strcpy,c,C,如果我有一个字符串数组 char* q[2]; q[0] = "Hello"; q[1] = "World"; char* x[2]; 我想把q[0]放在一个新的字符串数组中 char* q[2]; q[0] = "Hello"; q[1] = "World"; char* x[2]; 在x[0]中称为x,我应该使用strcpy还是仅此而已 x[0] = q[0]; 这似乎是可行的,但是没有使用strcpy在过去造成了一些问题 我应该这样做以防万一吗?有什么区别 char* a = m

如果我有一个字符串数组

char* q[2];
q[0] = "Hello";
q[1] = "World";
char* x[2];
我想把
q[0]
放在一个新的字符串数组中

char* q[2];
q[0] = "Hello";
q[1] = "World";
char* x[2];
在x[0]中称为x,我应该使用strcpy还是仅此而已

x[0] = q[0];
这似乎是可行的,但是没有使用strcpy在过去造成了一些问题

我应该这样做以防万一吗?有什么区别

char* a = malloc(strlen(q[0]) + 1);
strcpy(a, q[0]);
x[0] = a;

该赋值在不分配任何额外内存的情况下工作


如果使用
strcpy()
,则在进行复制之前必须为
x[0]
分配足够的内存(
strlen(q[0])+1
字节最小值),并且必须确保在适当的时间释放它。

没有一般规则,哪一个更好。这完全取决于字符串的预期用途

如果您不打算单独修改内存,只需分配指针就可以了

如果释放第一个指针,第二个指针中仍会有一个副本。但现在它是无效的。此外,如果您通过一个指针添加或更改内容,则此更改也将通过第二个指针可见。这是因为您使用的是相同的内存

如果复制字符串,则具有独立的内容。您可以通过第一个指针释放或修改,但仍然可以通过第二个指针使用它。 当然,如果复制到其他位置,还必须单独释放内存

当然,简单的作业速度更快。 哪一个更好取决于你的需要

我有一个字符串数组

char* q[2];
q[0] = "Hello";
q[1] = "World";
char* x[2];
嗯,不完全是<代码>q声明为

char* q[2];
这使得它成为一个由两个指针组成的数组,指向
char
。在C语言中,通常被称为字符串的是以NULL结尾的
char
数组

然后,为数组的每个元素指定两个值:

q[0] = "Hello";
q[1] = "World";
其中
“Hello”
“World”
都是字符串文本。这里不复制字符串,只复制指针

在代码的后面,您可以重新分配每个指针,如

q[0] = "Bye";
但任何尝试都会导致难以检测的bug

如果将其声明为指向const
char
的指针的数组,则更安全,这样在出现错误的情况下,至少错误消息会提供更多信息。例如,或


如果您需要可修改的字符串以及对这些对象生命周期的控制,那么您唯一的选择就是分配足够的内存并复制字符串。

要清楚,strcpy()没有任何“坏”的地方。;如果它“在过去给您带来了一些问题”,那是因为您的使用中出现了错误,而不是因为strcpy()的任何固有问题,那么您可能应该发布一个关于这一点的问题,以便纠正您的误解

字符串指针赋值和字符串复制之间的语义不同,因此它取决于您尝试执行的操作

x
是指针数组。任务:

x[0] = q[0];
不将
q[0]
指向的字符串复制到
x[0]
指向的内存中。而是将
x[0]
的值更改为
q[0]
引用的字符串的地址。因此,它们都引用内存中的同一字符串。不移动或复制任何字符串数据,在这种情况下,仅对字符串文字的引用:

q[0] --> "Hello"
          ^
          |
x[0] -----
从这个意义上讲,
x
不是您描述的“一个新的字符串数组”,而是指向相同字符串的指针数组。因此,这可能不是您想要的语义行为

如果要尝试:

strcpy( x[0], q[0] ) ;
这将是一个语义错误,因为在片段中,
x[0]
没有指向任何已定义的内存,因此,
q[0]
引用的字符串数据将被复制到某个未定义的位置,并产生未定义的结果-不好,即使它表面上看起来是有效的

如果
x[0]
引用了一些有效分配的空间,例如,声明为数组,则:

char x[2][128] ;
或被动态分配:

x[0] = malloc( 128 ) ;
或者首先分配给其他有效空间:

char a[120]
x[0] = a ;
或者动态分配
a
,如您问题中的示例所示

然后,
strcpy(x[0],q[0])
是一个有效的操作,它会将
q[0]
引用的字符串复制到
x[0]
引用的空间:

q[0] --> "Hello"

x[0] --> "Hello"
关键的是,在这种情况下,字符串不引用内存中的相同空间

请注意,如果您实际上想要字符串指针赋值语义(这可能不太可能),并且
q
指的是文字字符串常量,那么对于更安全的代码,您必须将数组声明为指向
const
数据的指针:

const char* q[2] ;
const char* x[2] ;
在任何情况下,
q
数组都应该声明为
const
,但是如果需要字符串复制语义,显然
x
不应该是const


通过声明它
const
,任何试图
strcpy()
到它的尝试都将在编译时决定性地失败,而不是出现一些未定义、错误和潜在的运行时行为。因此,如果这确实是您想要的,那么它将强制执行预期的语义。同样,它阻止您尝试修改
q[n]
引用的数据,这也是未定义的行为(但在现代桌面操作系统上通常会导致运行时错误)。

因此,在这种情况下,分配更好。当我在其他场景中不使用strcpy时,为什么有时我的值会发生变化?@melheitz我们无法判断哪一个更好。这取决于您对数组的使用。可能(赋值是最好的)-但这取决于您接下来对变量做什么。如图所示,字符串是字符串文字,您不应该修改
q
所指向的字符串(您永远不应该编辑字符串文字);。如果计划在
x
中编辑字符串,则需要分配空间并将字符串复制到该空间中。如果你打算让他们单独呆着,或者可能改变所指的内容(改变点