离开循环时矢量数据丢失
Vector Data Loss When Leaving A Loop
我不认为自己是一个编程新手,但我一直在努力理解向量在六个月的大部分时间里。
我试过在"生产"代码中使用向量,但它似乎从来没有像我期望的那样起作用。这个例子是我遇到的许多问题之一,正如标题所述,Vectors似乎在离开while循环后神秘地丢失了数据。这可能会归结为我只是使用了错误的向量,但我想认为我的过程至少是合理的。正如您将注意到的,这是一个对象向量,这可能也是问题的关键所在。
在我所做的这个例子中,一个char指针内部有一个随机字符被添加到向量中,正好是10次。每次都会擦除char指针的内容,并添加新内容以确保数据的唯一性。在离开循环并启动另一个循环以打印vector的内容之后,刚刚添加到vector中的数据都不存在了。为什么?
此外,从我看到的例子中,向量的初始化是非标准的,但似乎是使向量工作而不崩溃的唯一方法。
为我糟糕的格式道歉,代码块中的样式不完全是我如何格式化代码(括号间距稍微搞砸了)提前感谢!
#include <stdio.h>
#include <vector>
#include <stdlib.h>
int main( int argc, char * argv[ ] ) {
std::vector<char *> avector( 0 );
avector.reserve( 400 );
int counter = 0;
char * place;
bool ok;
Back:
if( counter == 10 ) {
counter = 0;
while( counter != 10 ){
printf( "Element %d: %sn", counter, avector.at( counter ) );
++counter
}
ok = false;
}
while( counter != 10 ) {
ok = true;
place = (char *)malloc( 10 * sizeof( char ) );
*place = (char)( ( rand( ) % 26 ) + 65 );
printf("Pre-placement, element %d: %sn", counter, place );
avector.push_back( place );
printf("Post-placement element %d: %sn", counter, avector.at( counter ) );
free( place );
++counter;
}
if( ok == true ) {
goto Back;
}
exit( 0 );
}
place = (char *)malloc( 10 * sizeof( char ) );
使用malloc
avector.push_back( place );
你把它推到向量
free( place );
然后,你删除它。指针仍然在向量中,但是内存地址不再属于你了。
另外,你是用c++编程,而不是C,所以不要使用printf, goto, malloc和free。
尽量不要使用new和delete,而是使用智能指针(c++ 11)
代码中的主要错误是您向vector添加了一个指针,但随后使存储在vector中的指针无效。
place = (char *)malloc( 10 * sizeof( char ) );
avector.push_back( place );
free( place ); // <<--- BUG; you destroyed what's pointed to by place
错误是place
和place
在avector
中添加的位置(例如,在avector[avector.size() - 1]
)都指向相同的内存位置,因此在给定的循环迭代中,free
指向place
与free
指向avector[avector.size() - 1]
相同。
你基本上是在自找麻烦。
我认为一个更简单的例子可以帮助你看得更清楚。这是您的代码的重构版本,使用适当的c++而不是c++和C的混合:#include <iostream>
#include <vector>
using namespace std;
int main( int argc, char * argv[ ] ) {
vector<char *> my_char_pointers;
cout << "Filling up vector ..." << endl;
for(int i = 0; i < 5; ++i) {
cout << "Adding address of " << char(65 + i) << " to vector ..." << endl;
my_char_pointers.push_back(new char(65 + i));
}
cout << "Printing vector ..." << endl;
for(int i = 0; i < my_char_pointers.size(); ++i)
cout << my_char_pointers.at(i) << endl;
cout << "Deleting char pointer vector elements ..." << endl;
for(int i = 0; i < my_char_pointers.size(); ++i)
delete my_char_pointers[i];
cout << "Printing vector of now-INVALID pointers ..." << endl;
for(int i = 0; i < my_char_pointers.size(); ++i)
cout << my_char_pointers.at(i) << endl;
cout << "Removing the now invalid pointers from vector ..." << endl;
my_char_pointers.clear();
return 0;
}
在我的Linux PC上运行它,你会得到以下输出:
$ g++ -o test test.cpp
$ ./test
Filling up vector ...
Adding address of A to vector ...
Adding address of B to vector ...
Adding address of C to vector ...
Adding address of D to vector ...
Adding address of E to vector ...
Printing vector ...
A
B
C
D
E
Deleting char pointer vector elements ...
Printing vector of now-INVALID pointers ...
��
`��
@��
���
Removing the now invalid pointers from vector ...
你的版本和我的版本之间的一些差异需要注意,包括错误修复和其他细节:
- 我创建,但不
delete
,vector
输入在同一循环(这是修复); - 你的代码很难遵循,使错误更难捕获/调试;
- 它使用
new
和delete
,这是在c++中分配/释放内存的正确方式(malloc
和朋友是C) - 它使用
<iostream>
中的cout
,这是在c++中打印输出的正确方式(printf
用于C) - 它使用正确的结构化代码,并且不依赖于
goto
[1],这导致了面条式代码; - 和我的代码更容易跟随/理解,使任何错误更容易找到/修复
如果你真的不想成为一个"编程新手",你需要在你的代码结构、简化逻辑和其他细节上下功夫。
还需要注意的是,你并没有真正的"objects"的vector
;你有一个指向char
s的指针向量。名为my_char_pointers
的vector
是一个对象,但它的内容是基本类型。(是的,术语确实有区别。)
[1]为什么在Dijkstra的名字上使用goto
语句?它们会给你自己和那些将来不可避免地需要阅读你代码的人带来很多麻烦。
- 与多个 for 循环与单个 for 循环 wrt 相关的性能从多映射获取数据
- OpenMP:for 循环避免数据竞争,而无需使用关键
- 有没有办法在C++中循环访问对象的不同数据成员
- C++ - 使用用户输入的字符串数据检查结构字符串数据(无限执行 while 循环)
- 类方法 - 数据结构中 For 循环的运行时错误
- 用于循环访问多个集合的数据结构
- 增强循环缓冲区push_back在前面插入数据
- 从文件导入数据时遇到问题.我有一个没完没了的循环
- 它不显示数据,只显示永无止境的循环
- C++:从文件中读取x y数据会产生无限循环吗
- C++ 中的类之间的数据重新循环 - 错误:'<class name>'未在此范围内声明
- 将结构数据存储在循环缓冲区中
- 利用输入文件中的数据(字符串和int)并在循环中利用
- boost::asio::async_read 无限循环,接收数据为零字节
- 如何使用for循环将数据保存在不同的文件中?
- C++ 数据结构队列:使用 for 循环查找队列中最大的元素
- C++ - 将数据插入到地图循环的地图中
- 输入数据类型检查循环未按预期工作 (C++)
- 如果输入变量的数据类型与以前不同,如何使我的循环仍然正常运行?
- 如何在每次循环迭代期间生成向量,存储数据,然后删除该向量?