传递字符数组时指针解除引用

时间:2017-05-28 20:11:04

标签: c arrays pointers

我很长时间没有接触过C,这些天决定提醒自己一些东西。我开始观看Jerry Chain在斯坦福大学的讲座,在他的一个例子中,他在第4讲中用C语言实现了通用交换:

  char* wife = strdup("Wilma");
  char* husband = strdup("Fred");

  cout<<husband<<endl<<wife<<endl;
  swap(&husband,&wife, sizeof(char*));
  cout<<husband<<endl<<wife<<endl;

这个函数中的所有东西似乎都没问题,但是,一旦传递了字符数组,就会出现&amp;一切似乎都有效。在他的示例中没有&amp; ,控制台输出是 Wilm和Freda 。然而,在我这方面,两个方面,该计划是完美的。

{{1}}

所以问题是,为什么它有效?它不应该正常工作。 &amp;取消引用指向实际值的指针,又名。字符数组。没有它应该指向指针地址本身。

问题来自此来源:https://see.stanford.edu/Course/CS107/200

2 个答案:

答案 0 :(得分:2)

在他的机器上,指针的大小是4个字节。这就是为什么&#34; Wilm和Freda&#34;,因为它正在交换前四个字节(sizeof(char*))。

由于char *是一个指向char数组的指针,你可以将指针交换到这些字符串,也可以交换字符串指向的内存。

如果机器使用64位,那么它会交换前8个字节,因此会复制整个字符串和一些垃圾。

const char string&#34; Wilma&#34;占用6个字节(对于null终止)。例如。 [&#39; W&#39;,&#39;我&#39; l&#39;,&#39; m&#39;,&#39; a&#39;,&#39; \ 0&#39]。 &#34;佛瑞德&#34;同样是5个字节:[&#39; F&#39;,&#39; r&#39;,&#39; e&#39;&#39; d&#39;&#39; \ 0&#39; ;。]

如果内存对齐,那么它可能如下所示:

['W', 'i', 'l', 'm', 'a', '\0', *, *, |'F', 'r', 'e', 'd', '\0', *, *, *] 

其中|是DWORD边界,*是垃圾。 64位是8个字节,因此您可能正在交换整个内存部分。

答案 1 :(得分:2)

  

它不应该正常工作。

是的,应该。

  

&amp;取消引用指向实际值的指针,又名。字符数组

没有。解除引用运算符为*&是运营商的地址。

  

没有它应该指向指针地址本身。

没有。指针指向字符数组。表达式的地址指向指针变量。

  

没有&amp;在他的例子中,控制台输出是Wilm和Freda。然而,在我这方面,两个方面,该计划是完美的。

此时,重要的是要记住,即使程序看起来像您预期的那样,它也不一定完美地工作

swap(husband,wife, sizeof(char*));的确切行为取决于指针变量的大小。如果指针变量大于字符数组的大小(5是较小的那个),则交换将复制整个字符数组并溢出,从而导致未定义的行为。

如果指针变量小于字符数组的大小,则不会复制数组的一部分,如讲师所示。在他的系统上,数据指针的大小为4。

给定的算法只能用于交换两个大小相同的对象。它不能用于交换两个不同大小的数组的内容,但它可以用来交换两个相同类型的指针。

当然,在用C ++编程时,使用C语言实现的自定义通用交换是愚蠢的。您可以使用std::swap代替 - 或针对您的特定类型优化的自定义代码。