是否使用strcpy

时间:2019-05-11 07:50:19

标签: c

如果我有一个字符串数组

char* q[2];
q[0] = "Hello";
q[1] = "World";

我想将q[0]放入新的字符串数组中

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;

4 个答案:

答案 0 :(得分:4)

该分配工作而不会分配任何额外的内存。

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

答案 1 :(得分:3)

需要明确的是,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,但显然,如果需要 string-copy 语义,x不应为const 。

通过声明为conststrcpy()的任何尝试都将在编译时确定性地失败,而不是具有一些未定义的,错误的和潜在的运行时行为。因此,如果确实符合您的意图,它将强制执行预期的语义。同样,它使您无法尝试修改q[n]所引用的数据,这也是未定义的行为(但通常会在现代台式机操作系统上导致运行时错误)。

答案 2 :(得分:1)

没有一般规则,哪个更好。这完全取决于您打算使用的字符串。

如果您不打算独立修改内存,则只需分配指针即可。

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

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

简单的分配当然更快。 哪个更好取决于您的需求。

答案 3 :(得分:1)

  

我有一个字符串数组

嗯,不完全是。 q被声明为

char* q[2];

这使它成为指向char 的两个指针的数组。在C中,通常称为 string 的是char的以NULL结尾的数组。

然后,将两个值分配给数组的每个元素:

q[0] = "Hello";
q[1] = "World";

"Hello""World"均为字符串文字。这里没有字符串被复制,只有指针被复制了。

稍后,您可以在代码中重新分配每个指针,例如

q[0] = "Bye";

但是尝试进行modify the charactersfree the pointers都会导致难以检测到错误。

将其声明为指向 const char的指针的数组将是更安全的,如果它们本意是未被触动的,那么在出现错误的情况下,至少是错误消息会提供更多信息。例如12

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