我正在尝试使用动态内存分配创建c字符串的2D数组(用于特定的学校练习;我被迫使用c字符串进行练习)。但是,似乎在访问和写入数组的第二个索引(第二个子数组)时,使用的实际内存位置与第一个索引相同。
代码:
#include <iostream>
#include <string>
int main()
{
int n_names; std::string current; const int SPACE_FOR_EACH_NAME = 100;
std::cout << "How many names to input? "; std::cin >> n_names; std::cin.ignore();
//dynamically allocate a multi-dimensional array
char** names;
names = new char* [n_names];
for (int i = 0; i < n_names; i++)
names[i] = new char[SPACE_FOR_EACH_NAME];
int count = 0;
while (count < n_names) {
std::cout << "Name " << ++count << ": ";
std::getline(std::cin, current);
names[count-1] = (char*) current.c_str(); //THE TROUBLE SEEMS TO BE HERE
}
for (int i = 0; i < n_names; ++i) {
for (int j = 0; j < SPACE_FOR_EACH_NAME; ++j) {
if (names[i][j] == '\0') break; //termination of the current name
std::cout << names[i][j];
}
std::cout << "\n";
}
//free allocated memory
for (int i = 0; i < n_names; ++i)
delete[] names[i];
delete[] names;
}
调试器在修改“名称”数组时显示的内容(考虑用户输入2个名称):
+ names[count-1] 0x00affbe8 "dude" char * //here count is 1
+ names[count-1] 0x00affbe8 "noice" char * //here count is 2
并且控制台只打印两次“ noice”。怎么了?
current.c_str()
的结果永远不应存储任何时间。这样做是不确定的行为,但有可能,因为这里指向的内存将被重用。
您将current.c_str()
中的char *放入names[0]
,然后将新值放入current
,然后将current.c_str()
放入names[1]
。但是因为您已经更改了current
,所以您也更改了names[0]
。
此外,在两种情况下,您都将丢弃已经使用names[i] = new char[SPACE_FOR_EACH_NAME];
创建的指针>
这将分配一个内存块并将其地址放入names[0]
(作为具体示例,请参见0
)。 names[0]
发生的下一件事是names[0] = (char*) current.c_str();
,它将另一个地址放入变量中。 new
返回的地址完全丢失,导致内存泄漏。
代替
names[count-1] = (char*) current.c_str();
尝试
std::strcpy(names[count-1],current.c_str())