[英]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数组。 您需要修复一些问题:
由于portarray被声明为指针数组,因此需要单独的缓冲区指向。
将portarray更改为声明为std :: string的数组。 您会得到一份副本。 因此,您将拥有不同的价值。
将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.