繁体   English   中英

是否使用strcpy

[英]To use strcpy or not

如果我有一个字符串数组

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;

分配工作时不分配任何额外的内存。

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

要清楚, 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]引用的数据,这也是未定义的行为(但通常会在现代桌面操作系统上导致运行时错误)。

没有一般规则,哪一个更好。 这完全取决于您对字符串的意图用法。

如果您不打算单独修改内存,只需指定指针即可。

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

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

当然,简单的任务更快。 哪一个更好取决于您的需求。

我有一个字符串数组

嗯,不太好。 q被声明为

char* q[2];

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

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

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

"Hello""World"都是字符串文字 这里没有复制字符串,只有指针。

稍后在代码中你可以重新分配每个指针,就像在

q[0] = "Bye";

但任何修改字符释放指针的尝试都会导致很难发现错误。

将它声明为指向const char的数组会更安全,如果它们是不受影响的,那么在出错的情况下,至少错误消息会提供更多信息。 例如12

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM