繁体   English   中英

我的for循环使每个值成为最后一个值(C ++)

[英]my for loop is making every value the last value (C++)

我有一个用户输入一个值,然后根据该值和以下31个值定义端口。 这些端口然后应存储在数组中,但是出于某种原因,当我从数组中调用时,每个值都是最后一个值。 (例如,如果用户输入5000,则数组中的每个值最终都是5031)。 将实际数字存储在数组中是有问题的,因为如果我在创建值时将其打印出来,它们都是正确的。 不好意思的代码,我是新手。 谢谢!

//enter own ports   
using namespace std;
    cout << "enter a port number between 1000-9999: "; // gets port from user input
    cin >> startingport;


for (int i=0; i<32; i++) // defines 32 ports starting with user input
    {
    sprintf(portchar, "%d", startingport+i);
    cout << "defining port: " << portchar << endl; // gives correct value
    portarray[i] = portchar;
    }

cout << portarray[0] << endl; // gives incorrect value

抱歉,应该在此之前-我在另一个文件中有定义。 我需要port成为角色,因此portchar

static int startingport;
static char portchar[6];
static char *portarray[32];

当您反复使用“ portchar”进行打印时,它们将指向相同的基础值,而它恰好是静态char。

portarray [0]-> portarray [1]-> ... portarray [2]->所有都指向“ portchar”

它们都指向共享char数组。 您需要修复一些问题:

  1. 由于portarray被声明为指针数组,因此需要单独的缓冲区指向。

  2. 将portarray更改为声明为std :: string的数组。 您会得到一份副本。 因此,您将拥有不同的价值。

  3. 将portarray保留为指针数组,但是,为循环的每次迭代分配一个新的portchar并存储这些指针。

_3不好,因为您必须自己管理内存。

_2更好,并且将std :: vector <>用于portarray。

_1正在生成字符串的副本,您需要确定是否要支付该费用。

首先,我想回应Mike Seymour的评论,即您应该使用std::string s和一个容器,而不是char**char[] 更高级别的抽象有助于减轻许多与指针管理和算术相关的常见问题。

就是说,这是一个很好的教学时间。

什么地方出了错

让我们开始告诉自己,指针( * )只不过是一个地址。 就像我住在第一街555号一样,内存中的所有对象都有一个地址。 如果我搬出我的住址而其他人搬进去,当有人问谁住在第一街555号时,那一刻的答案将是搬进来的人, 而不是我。

如果指针只是地址,那么指针数组是什么? 好吧,这只是地址列表! 想象一个带有空槽的列表,该列表可以容纳32个地址。 这就是portarray

那你的循环做什么? 好吧,这里有三个基本操作:

sprintf(portchar, "%d", startingport+i);

这相当于有人进入了地址portchar 地址仍然相同,现在有一些新内容。

cout << "defining port: " << portchar << endl;

这与询问谁住在该地址相同。 当然,您知道这是什么,这只是startingport+1因为startingport+1刚刚移入!

最后:

portarray[i] = portchar;

请密切注意这一点。 这表示将地址portchar复制到您的地址列表中。 假设您有一张纸,然后写下了"0: 555 First St" 不是复制那个地址的人,而是复制地址本身。 此循环的下一个迭代,当需要再次写下该地址时,我们将写入"1: 555 First St" ,与之前相同。

因此,在循环结束时,您将获得一个不错的地址列表,并且所有地址都完全相同,因为当然您实际上从未真正更改过循环中的地址

您可以做什么(不使用std::string

如果您愿意手动管理portarray指向的内存,则可以使用堆分配的内存来解决问题。 这是必需的,因为您需要可以将32唯一地址放入portarray 您静态分配的portchar给您一个地址不足。

// Assuming you've removed your portchar declaration
for (int i=0; i<32; i++) // defines 32 ports starting with user input
{
    portarray[i] = new char[6]; // This dynamically allocates memory
    sprintf(portarray[i], "%d", startingport+i);
    cout << "defining port: " << portarray[i] << endl; // gives correct value
}

cout << portarray[0] << endl; // gives correct value

要稍后释放内存,您必须执行以下操作:

for (int i=0; i<32; i++)
{
    delete[] portarray[i];
}

看起来很乱,那是因为。 正如其他人所建议的那样,您可以通过使用std::string和container来避开这个雷区。 如果您的代码适合这些抽象,我强烈建议您使用它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM