首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解char *、char[]和strcpy()

理解char *、char[]和strcpy()
EN

Stack Overflow用户
提问于 2014-08-26 09:55:32
回答 4查看 15.9K关注 0票数 8

我的理解如下:

  • char *指向一个字符串常量,修改它指向的数据是未定义的。但是,您可以更改它指向的位置。
  • char[]指的是您可以更改的内存块。您可以更改它的内容,但不能更改它所指的内容。
  • strcpy(dest, src)src复制到dest中。

我的问题是,使用strcpy()dest作为已经指向的char * (我相信旧内容将被strcpy()覆盖--这是未定义的行为)是否不正确?

例如:

代码语言:javascript
复制
char *dest = malloc(5);
dest = "FIVE";

char *src = malloc(5);
src = "NEW!";

strcpy(dest, src); /* Invalid because chars at dest are getting overwritten? */
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-08-26 10:01:25

不幸的是,你的理解并不完全正确。

char *指向字符数据,因为其中没有const,所以可以写入指向的数据。

然而,完全有可能做到这一点:

代码语言:javascript
复制
char *a = "hello";

这为您提供了一个只读数据的读/写指针,因为字符串文本存储在只读内存中,而不是语言的语法“考虑”常量。

最好将上面的内容写成:

代码语言:javascript
复制
const char *a = "hello";

为了更清楚地说明您不能修改a指向的数据。

此外,您的示例混合了malloc()和赋值是错误的。

这是:

代码语言:javascript
复制
char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */

是不好的代码,你不应该这么做。它简单地用一个指向字符串"FIVE"的指针覆盖由"FIVE"返回的指针,该指针存在于(同样是只读的)内存中,作为字符串文本。

使用字符串数据使新分配的内存无效的正确方法是使用strcpy()

代码语言:javascript
复制
char *dest = malloc(5);
if(dest != NULL)
  strcpy(dest, "five");

注意,检查malloc()的返回值是个好主意。

对同一个内存进行多次写入是没有问题的,这是C中的一个非常基本的概念;变量表示内存,可以在不同的时间通过“写入”获得不同的值。

简单的事物,如:

代码语言:javascript
复制
int a = 2;

printf("a=%d\n", a);
a = 4;
printf("a=%d\n", a);

演示了这一点,当然,它对于字符串也很好,因为它们只是内存块。

您可以扩展上面的malloc()-based示例:

代码语言:javascript
复制
char *dest = malloc(5);
if(dest != NULL)
{
  strcpy(dest, "five");
  printf("dest='%s'\n", dest);
  strcpy(dest, "four");
  printf("dest='%s'\n", dest);
  strcpy(dest, "one");
  printf("dest='%s'\n", dest);
}

它将印刷:

代码语言:javascript
复制
dest='five'
dest='four'
dest='one'
票数 16
EN

Stack Overflow用户

发布于 2014-08-26 10:24:57

我的理解如下:

  • char *指向一个字符串常量,修改它指向的数据是未定义的。但是,您可以更改它指向的位置。

在这里,您指的是一个类似于

代码语言:javascript
复制
char * string = "mystring";

您是对的,做string[1]='r';是没有定义的。但这并不是因为char *,而是因为字符串文字涉及到一种将其放入只读内存的方式。

把这个和

代码语言:javascript
复制
char string[] = "mystring";

我在RAM中定义了一个数组,将该字符串放入其中。这里允许做string[1] = 'r';,因为我们处于正常的数据内存中。

这似乎支持了你的假设,但以以下为例:

代码语言:javascript
复制
char string[] = "mystring";
char * string2 = string;

在这里,string2[1] = 'r';是有效的,因为它指向了写入也可以的位置。

char[]指的是一个内存块,您可以更改它的内容,但不能更改它引用的内容。

是的,因为这里的名称只是变量的名称,而不是指针。

strcpy( dest,src)将src复制到dest中。

正确的。

我的问题是,如果使用strcpy()作为char *而使用strcpy()是否不正确,它已经指向某些内容(正如我所设想的那样,原来的内容将被strcpy()覆盖--这是未定义的行为)?

这取决于你所说的“已经指向某物”.

例如: char *dest = malloc(5);dest =“5”;char *src = malloc(5);src = "NEW!";strcpy( dest,src);/*无效,因为 覆盖?*/

在这里,你再次混淆了几件事情。

首先,dest指向一个全新的内存块。之后,您让它指向无法写入的其他地方,内存块丢失(内存泄漏)。

同样的情况发生在src上。

所以strcpy()失败了。

你能做到的

代码语言:javascript
复制
char *dest = malloc(5);

char *src = "NEW!";

strcpy(dest, src);

在这里,dest指向可写的位置,src指向有用的数据。

票数 4
EN

Stack Overflow用户

发布于 2014-08-26 10:29:22

快速分析:

代码语言:javascript
复制
char *dest = malloc(5);
// 'dest' is set to point to a piece of allocated memory
// (typically located in the heap)
dest = "FIVE";
// 'dest' is set to point to a constant string
// (typically located in the code-section or in the data-section)

您要给变量dest分配两次,所以很明显,第一次赋值没有任何意义。

就像在写:

代码语言:javascript
复制
int i = 5;
i = 6;

除此之外,您“丢失”了所分配内存的地址,因此您以后将无法释放它。

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

https://stackoverflow.com/questions/25502916

复制
相关文章

相似问题

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