我有两种代码变体:
第一:
void PrintMem(const int* memarr,const size_t size) {
for (size_t index = 0; index < size; ++index) {
std::cout << '<'<<(index+1)<<"> "s<<*(memarr + index) << std::endl;
}
}
void FillMem(int* memarr, const size_t size) {
srand(time(0));
for (size_t index = 0; index < size; ++index) {
*(memarr + index) = rand() % 100;
}
}
int main() {
const int size_iter = 10000000;
int n = 30;
int* ptr = nullptr;
int size = size_iter;
for (int i = 1; i <= n; ++i) {
size = size_iter * i;
if (i == 1) {
ptr = (int*)malloc(size * sizeof(int));
}
else {
ptr = (int*)realloc(ptr, size * sizeof(int));
}
if (ptr == nullptr) {
printf("memory allocation error\n");
break;
}
std::cout << '[' << i << ']';
printf(" address: %p", (void*)ptr);
std::cout << ", size: "s << size;
std::cout << " *********************" << std::endl;
FillMem(ptr, size);
//PrintMem(ptr, size);
}
if (ptr != nullptr) {
free(ptr);
}
}
第二:
void PrintMem(const int* memarr,const size_t size) {
for (size_t index = 0; index < size; ++index) {
std::cout << '<'<<(index+1)<<"> "s<<*(memarr + index) << std::endl;
}
}
void FillMem(int* memarr, const size_t size) {
srand(time(0));
for (size_t index = 0; index < size; ++index) {
*(memarr + index) = rand() % 100;
}
}
int main() {
const int size_iter = 10000000;
int n = 30;
int* ptr = nullptr;
int size = size_iter;
for (int i = 1; i <= n; ++i) {
size = size_iter * i;
int* new_ptr = nullptr;
if (i == 1) {
new_ptr = (int*)malloc(size * sizeof(int));
}
else {
new_ptr = (int*)realloc(ptr, size * sizeof(int));
}
if (new_ptr == nullptr) {
printf("memory allocation error\n");
break;
}
ptr = new_ptr;
std::cout << '[' << i << ']';
printf(" address: %p", (void*)ptr);
std::cout << ", size: "s << size;
std::cout << " *********************" << std::endl;
FillMem(ptr, size);
//PrintMem(ptr, size);
}
if (ptr != nullptr) {
free(ptr);
}
}
释放数组内存的正确方法是什么?
if (ptr != nullptr) {
free(ptr);
}
或者:
if (ptr != nullptr) {
for (int i = 0; i < size; ++i) {
free((ptr + i));
}
free(ptr);
}
我尝试了这两种方法。
我认为第二种变int* new_ptr
体会更好,因为它至少会保留之前的内存调整大小迭代。
我只需要知道如何优化这一点,以及仅释放是否正确ptr
或者我是否需要释放每个内存块?
5
最佳答案
1
您仅调用malloc()
一次来创建数组,并realloc()
多次调用来重新分配数组。只有一个数组,因此您free()
只需调用一次即可释放该数组。不要尝试free()
单个元素,因为它们不是malloc
单独执行的。free()
每次成功的 malloc()
/执行一次realloc()
。
另外,您不需要nullptr
在调用之前检查free()
,因为它已经在内部处理了。
此外,如果realloc()
失败,原始数组不会受到影响,但您将ptr
无条件覆盖变量,因此会泄漏现有数组。您需要在重新分配变量之前realloc()
检查是否失败。ptr
附注:剩余的代码还有一些其他的小问题:
-
您应该使用
memarr[index]
而不是*(memarr + index)
。 -
不要
srand()
多次调用。只需调用一次即可main()
。 -
"> "s
应该只是"> "
,没有必要强迫它std::string
只是打印它,因为operator<<
可以很好地处理字符串文字(正如您的其他一些打印中所证明的那样)。 -
你不应该
printf()
和混合std::cout
。坚持使用其中一个。
尝试一些更像这样的东西:
void PrintMem(const int* memarr, const size_t size) {
for (size_t index = 0; index < size; ++index) {
std::cout << '<' << (index+1) << "> " << memarr[index] << '\n';
}
}
void FillMem(int* memarr, const size_t size) {
for (size_t index = 0; index < size; ++index) {
memarr[index] = rand() % 100;
}
}
int main() {
srand(time(0));
const int size_iter = 10000000;
int n = 30;
int* ptr = nullptr;
for (int i = 1; i <= n; ++i) {
int size = size_iter * i;
if (i == 1) {
ptr = static_cast<int*>(malloc(size * sizeof(int)));
if (ptr == nullptr) {
std::cerr << "memory allocation error\n";
break;
}
}
else {
int *new_ptr = static_cast<int*>(realloc(ptr, size * sizeof(int)));
if (new_ptr == nullptr) {
std::cerr << "memory reallocation error\n";
break;
}
ptr = new_ptr;
}
std::cout << '[' << i << ']';
std::cout << " address: " << static_cast<void*>(ptr);
std::cout << ", size: " << size;
std::cout << " *********************\n";
FillMem(ptr, size);
//PrintMem(ptr, size);
}
free(ptr);
}
话虽如此,你真的不应该在 C++ 中使用malloc
/ 。而是使用,让它为你处理内存,例如:realloc()
std::vector
#include <vector>
void PrintMem(const std::vector<int> &arr) {
for (size_t index = 0; index < arr.size(); ++index) {
std::cout << '<' << (index+1) << "> " << memarr[index] << '\n';
}
}
void FillMem(std::vector<int> &arr) {
for (size_t index = 0; index < arr.size(); ++index) {
memarr[index] = rand() % 100;
}
}
int main() {
srand(time(0));
const int size_iter = 10000000;
int n = 30;
std::vector<int> arr;
for (int i = 1; i <= n; ++i) {
int size = size_iter * i;
arr.resize(size);
std::cout << '[' << i << ']';
std::cout << " address: " << static_cast<void*>(arr.data());
std::cout << ", size: " << size;
std::cout << " *********************\n";
FillMem(arr);
//PrintMem(arr);
}
}
您还应该考虑使用库中的<random>
,而不是使用 C 风格的rand()
。
另外,考虑使用,和如,等。
简而言之,尽可能避免在 C++ 中使用 C 主义。C 和 C++ 可能曾经有共同的传统,但它们已经演变成截然不同的语言。
|
malloc
(或calloc
或realloc
)返回一个指针;您应该释放该指针。此外,free
正确处理空指针,因此您无需测试。–
malloc
和?您应该使用“动态数组”。free
std::vector
–
(int *) ...
),那么您应该将其视为您可能做错了什么的迹象。–
p
和索引i
,表达式*(p + i)
完全等于。p[i]
使用数组索引语法通常可以使代码一目了然(并且编写起来更少)。–
rand() % 100
”——哎哟;1) 不要使用rand()
2) 不要使用模数来将值缩小到某个范围,这样会破坏平均值,还会使某些数字比其他数字更有可能。我们有是有原因的。您可能想观看此视频:。–
|