【问题标题】:C++ pointer array of structure结构体的C++指针数组
【发布时间】:2017-11-02 07:22:51
【问题描述】:
#include<iostream.h>
#include<conio.h>
#include<string.h>
#include<stdio.h>

struct telephone
{
    char name[10];
    char tno[9];
};

void main()
{ 
    telephone a[5];
    clrscr();
    telephone* p;
    p = a;
    strcpy(a[0].name, "Aditya"); // initializing the array
    strcpy(a[1].name, "Harsh");
    strcpy(a[2].name, "Kartik");
    strcpy(a[3].name, "Ayush");
    strcpy(a[4].name, "Shrey");
    strcpy(a[0].tno, "873629595");
    strcpy(a[1].tno, "834683565");
    strcpy(a[2].tno, "474835595");
    strcpy(a[3].tno, "143362465");
    strcpy(a[4].tno, "532453665");

    for (int i = 0; i < 5; i++)
    {  
        puts((p+i)->name);cout<< " ";   //command for output
        puts((p+i)->tno );cout<<endl;
    }
    getch();
}

在这段代码中,在获取输出时,我没有得到名称的输出。我只得到(p+0)-&gt;name 的输出而不是其他任何东西,但是如果我不初始化电话号码,那么我会得到姓名的输出。

【问题讨论】:

  • 用例如char tno[9] 你有一个 八个 个字符的“字符串”。请记住,C++ 中的 char 字符串实际上称为 null-terminated 字节字符串。不要忘记终止符的空间,否则您将超出界限并拥有undefined behavior
  • 为什么要使用p?表达式(p + i)-&gt;name 等于p[i].name 当然与a[i].name 相同。
  • 请考虑切换到std::string 而不是c-strings,以及cout 而不是puts。智能指针而不是原始指针。并且还可以考虑切换到一些新的 IDE。
  • include&lt;iostream.h&gt; 使用本世纪的编译器。

标签: c++ arrays pointers struct


【解决方案1】:

struct 存储在连续的内存位置,因此当您分配 tno 变量时,尝试将高于其边界大小的数据存储在其中,剩余位得到添加到下一个内存位置

在你的代码tno [9],所以它可以存储ma​​x 9个字符,虽然你只给它9个字符,但是什么strcpy 所做的是它还将\0 添加到末尾,它尝试将其添加到tno [10]它不存在并且超出范围并将其存储在其他一些内存位置,可能对于下一个数组,这会导致未定义的行为。

你只需要改变结构定义如下:

struct telephone
{ 
   char name[10];
   char tno[10]; // if you intend to store 9 digit number
 }; 

请记住,如果您打算将 x 个字符存储在字符数组中,那么您的数组大小必须为 x + 1。如果使用字符数组似乎很难,也许你可以使用std::string

【讨论】:

  • "strcpy 的作用是它还在末尾添加了\n" 不,strcpy 不会在末尾添加换行符。但是,strcpy 确实从字符串文字 | 复制了空终止符,即 '\0'"它尝试将其添加到tno [10]" 不,空终止符位于索引 9 处(超出输出数组的范围)。
【解决方案2】:

电话号码至少要大一号。 电话号码在下一个数组中超出一个字节,并将名称更改为 '\0'

strcpy(a[0].tno ,"873629595" );

从 [1].name 转为

"Harsh\0"

进入

"\0arsh\0"

结构布局

+---+---+---+---+---+---+---+---+---+---+
| A | d | i | t | y | a | \0|   |   |   |
+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+
| 8 | 7 | 3 | 6 | 2 | 9 | 5 | 9 | 5 | 
+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+
| \0| a | r | s | h | \0|   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+
| 8 | 3 | 4 | 6 | 8 | 3 | 5 | 6 | 5 | 
+---+---+---+---+---+---+---+---+---+

没有一个电话号码有空终止符的空间,并且正在覆盖其空间之外。这实际上是下一个数组元素名称。

【讨论】:

  • @Vedant 为什么会有填充?
  • 我认为包含 char 和 char [] 的结构可以有效地未对齐,并且不需要填充。我可以看到观察到的 OP 行为的唯一方法是通过没有填充的结构。
  • @mksteve OP 说他没有得到名称的输出,但根据您在答案中创建的图像,只有第一个和最后一个字符有 \0,所有其他字符都有有效字符,那么为什么不打印这些字符...?为什么 OP 得到完全空白的输出...?
  • @Vedant '\0' 标记字符串的结尾,后面的所有内容都不考虑
猜你喜欢
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 2023-03-07
相关资源
最近更新 更多