c++ - 将指针数组推入 std::vector 避免使用 push_back 复制对象
问题描述
在此代码中,在 for 循环中创建了一个指针数组,newData
然后将其推入一个 vectortestData
中。指针存储在向量中std::vector<testData*>
。
我担心的是我需要确保指针引用的对象在向量持有对它们的引用时仍然有效。我是否会通过newData = new unsigned char[frameSize];
在 for 循环中调用该行来丢失此引用?
我主要是想避免使用push_back
.
如何创建一个unsigned char*
随机字符数组(这里我只使用'a'
),然后将这些数组推送到向量?
int numFrames = 25;
int frameSize = 100;
std::vector<unsigned char*> testData;
unsigned char *newData;
for (int i = 0; i < numFrames; i++) {
newData = new unsigned char[frameSize];
for (int j = 0; j < frameSize; j++) {
newData[j] = 'a'; // fill the frame with random data, 'a' here
}
testData.push_back(newData);
newData = 0; // ??
memset(&newData, 0, frameSize); // ??
}
std::cout << " testData " << testData.size() << "\n";
解决方案
我是否会通过
newData = new unsigned char[frameSize];
在 for 循环中调用该行来丢失此引用?
不,如果做得正确,这是完全可行的。
但是,您的代码中存在一些问题,在memset(&newData, 0, frameSize); // ??
您设置指针占用的内存的行中,该指针通常不超过 8 个字节(取决于体系结构),大小为 100 个字节,这会调用未定义的行为。您可能想要:
memset(&newData, 0, sizeof newData); // ??
但这不会满足您的需要,使指针无效会使您无法访问数据,您不希望这样,并且您在每次迭代中都将相同的指针推向向量,您最终会得到一个向量填充了指向相同数据的相同指针。
for
在循环内移动它的声明可以解决这个问题。您没有复制任何数据,而是在每次新迭代时将指向新内存位置的新指针推入向量中。
如何创建一个
unsigned char*
随机字符数组(这里我只使用'a'
),然后将这些数组推送到向量?
您的代码应如下所示:
#include <iostream>
#include <vector>
#include <ctime>
int main()
{
srand(time(0)); //seed, not the best randomizer but does the job here
const size_t numFrames = 25; //sizes can/should be constant and unsigned
const size_t frameSize = 100;
std::vector<unsigned char *> testData;
for (size_t i = 0; i < numFrames; i++)
{
//in each iteration a new pointer
unsigned char *newData = new unsigned char[frameSize];
for (size_t j = 0; j < frameSize; j++)
{
newData[j] = 'a' + rand() % 26; //random alphabetic char
}
testData.push_back(newData);
}
std::cout << "testData " << testData.size() << "\n";
for (size_t i = 0; i < numFrames; i++) //test print
{
for (size_t j = 0; j < frameSize; j++)
{
std::cout << testData[i][j];
}
std::cout << "\n";
}
}
不用说,您应该delete
在不再需要之前分配的内存。
如果你想要一个更好的随机引擎,你可以查看这篇文章Generate random numbers using C++11 random library。
一些注意事项:
正如您可能知道的那样,newData
指针指向的数据不能被视为字符串,也就是以空字符结尾的字符数组,因为它们当然不是以空字符结尾的。
您需要手动管理分配的内存,也就是说,手动保留的内存也必须在完成后手动删除。
代码更正是针对您的代码的,但正如WhozCraig 正确指出的那样,您最好使用 STL 容器而不是指针。
推荐阅读
- java - 如何在 EditText 中添加数字分隔符
- java - 如何将两个或多个字符串数组列表的排列组合创建为一个组合列表
- laravel - 在 Laravel 5.7 中修改 getRouteKeyName
- javascript - Phaser3 + ES6 类:如何保持范围从创建到更新
- html - 如何在 HTML 中以列方式组合两个框架并使其成为一个可滚动页面?
- vuejs2 - 封装使用类语法的 vue 组件
- laravel - laravel vuejs/axios put request Formdata 为空
- python - 如何找到最优化的 if 语句序列?
- python - 将单个系数作为数组给出时如何调用它们?
- javascript - 单击时在 Select2 多选上指定边框颜色