理解char *,char []和strcpy()

时间:2014-08-26 09:55:32

标签: c arrays string pointers strcpy

我的理解如下:

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

  • char[]指的是一块内存,您可以更改其内容,但不能更改内容。

  • strcpy(dest, src)src复制到dest

我的问题是,使用strcpy() destchar * 已经指向某事是不正确的(因为我相信旧的{/ 1}}内容将被strcpy()覆盖 - 这是未定义的行为)?

例如:

char *dest = malloc(5);
dest = "FIVE";

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

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

4 个答案:

答案 0 :(得分:11)

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

char *指向字符数据,因为那里没有const,您可以写入指向的数据。

但是,完全可以这样做:

char *a = "hello";

它为您提供了一个只读数据的读/写指针,因为字符串文字存储在只读存储器中,但不是"考虑"语言的语法不变。

将上述内容写成:

更好
const char *a = "hello";

更清楚地说明您无法修改a所指向的数据。

此外,混合malloc()和分配的示例是错误的。

此:

char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */

代码不好,你永远不应该这样做。它只是用一个指向字符串dest的指针覆盖"FIVE"返回的指针,该字符串作为字符串文字存在于(再次,只读)内存中。

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

char *dest = malloc(5);
if(dest != NULL)
  strcpy(dest, "five");

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

对同一个内存进行多次写入没有问题,这是C语言中的一个非常基本的想法;变量代表记忆,并且可以通过"写在"来为不同的时间赋予不同的值。

简单的事情:

int a = 2;

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

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

您可以扩展以上基于malloc()的示例:

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);
}

它会打印出来:

dest='five'
dest='four'
dest='one'

答案 1 :(得分:3)

  

我的理解如下:

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

这里你指的是像

这样的表达式
char * string = "mystring";

你是对的,string[1]='r';未定义。但这不是因为char *,而是因为字符串文字涉及到它被放入只读内存的方式。

将此与

进行比较
char string[] = "mystring";

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

这似乎支持你的假设,但请考虑一下:

char string[] = "mystring";
char * string2 = string;

此处string2[1] = 'r';有效,因为它指向写作正常的位置。

char[] refers to a block of memory that you can change its contents but not what it refers to.

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

strcpy(dest, src) copies src into dest.

右。

  

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

这取决于你的意思"已经指向了什么" ...

  

例如:

char *dest = malloc(5);
dest = "FIVE";

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

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

覆盖? * /

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

首先,你dest指向一个全新的记忆块。之后,你可以指向其他你无法写入的地方,并且内存块丢失(内存泄漏)。

src也是如此。

所以strcpy()失败了。

你可以做到

char *dest = malloc(5);

char *src = "NEW!";

strcpy(dest, src);

此处dest指向可写地点,src指向有用数据。

答案 2 :(得分:2)

快速分析:

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两次,所以很明显,第一项任务没有意义。

就像写作:

int i = 5;
i = 6;

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

答案 3 :(得分:1)

char *是指向内存地址的指针,因此您可以修改该地址中包含的信息。

char *和char []之间的区别在于char []不是动态的,你不能改变它的大小。此外,char *指向堆中的地址,而char []存储在程序的堆栈中。

你可以将strcpy与指针和数组一起使用,它可以工作,因为两者的数据都可以被覆盖。