首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否使用strcpy

是否使用strcpy
EN

Stack Overflow用户
提问于 2019-05-11 15:50:19
回答 4查看 90关注 0票数 2

如果我有一个字符串数组

代码语言:javascript
复制
char* q[2];
q[0] = "Hello";
q[1] = "World";

我想把q[0]放在一个新的字符串数组中

代码语言:javascript
复制
char* x[2];

在x中称为x,我应该使用strcpy还是只使用这个?

代码语言:javascript
复制
x[0] = q[0];

这似乎是有效的,但没有使用strcpy在过去造成了一些问题。

我应该这样做以防万一吗?有什么关系?

代码语言:javascript
复制
char* a = malloc(strlen(q[0]) + 1);
strcpy(a, q[0]);
x[0] = a;
EN

回答 4

Stack Overflow用户

发布于 2019-05-11 15:57:42

该分配无需分配任何额外的内存即可工作。

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

票数 4
EN

Stack Overflow用户

发布于 2019-05-11 17:42:16

需要明确的是,strcpy()没有什么“损坏”;如果它“在过去造成了一些问题”,那是因为您使用上的错误,而不是strcpy()的任何内在问题,您可能应该发布一个关于这方面的问题,以便纠正您的误解。

字符串指针赋值和字符串复制之间的语义不同,因此它取决于您试图做什么。

x是一个指针数组。作业:

代码语言:javascript
复制
x[0] = q[0];

不将q[0]指向的字符串复制到x[0]指向的内存。相反,它将x[0]的值更改为q[0]引用的字符串的地址。所以它们都引用了内存中的同一个字符串。不移动或复制字符串数据,只移动或复制本例中对字符串文字的引用:

代码语言:javascript
复制
q[0] --> "Hello"
          ^
          |
x[0] -----

从这个意义上说,x不是您所描述的“新的字符串数组”,而是指向相同字符串的指针数组。所以可能不是你想要的语义行为。

如果您尝试执行以下操作:

代码语言:javascript
复制
strcpy( x[0], q[0] ) ;

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

如果x[0]引用了一些有效分配的空间,例如,任何一个都被声明为一个数组,如下所示:

代码语言:javascript
复制
char x[2][128] ;

或被动态分配:

代码语言:javascript
复制
x[0] = malloc( 128 ) ;

或者首先被分配到其他有效的空间:

代码语言:javascript
复制
char a[120]
x[0] = a ;

或者动态分配a,如您问题中的示例所示。

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

代码语言:javascript
复制
q[0] --> "Hello"

x[0] --> "Hello"

关键的是,在这种情况下,字符串并不指向内存中的相同空间。

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

代码语言:javascript
复制
const char* q[2] ;
const char* x[2] ;

在这种情况下,q数组在任何情况下都应该声明为const,但如果您想要字符串复制语义,显然不应该将x声明为const。

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

票数 3
EN

Stack Overflow用户

发布于 2019-05-11 16:06:22

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

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

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

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

当然,简单的赋值更快。哪一个更好取决于你的需求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56088320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档