带有指向数组的指针的过程重新分配
Procedural realloc with pointer to an array
为了保持代码整洁(而且过于复杂,就像我所做的那样),我希望main()函数将指向int/数组的/指针传递给函数。然后,该函数将按程序扩展数组并添加与条件匹配的新条目。
我有一个有效的代码,但由于某种原因valgrind
报告内存泄漏(来自主数组)。而且,我不喜欢在重新分配数组之前必须如何分配数组。
#include <iostream>
#include <cstdlib>
int get_divisors(int num_input, int *num_result);
int main()
{
int num_input, *num_result = (int*)malloc(sizeof(int));
std::cin >> num_input;
int num_size = get_divisors(num_input, num_result);
for (int loop_1 = 0; loop_1 < num_size; loop_1++){
std::cout << num_result[loop_1] << "n";
}
free(num_result);
}
int get_divisors(int num_input, int *num_result)
{
int num_count = 0;
for (int loop_1 = 1; loop_1 < num_input; loop_1++){
if (num_input % loop_1 == 0){
num_count++;
num_result = (int*)realloc(num_result, num_count*sizeof(int));
num_result[num_count - 1] = loop_1;
}
}
return num_count;
}
瓦尔格林德: (--泄漏检查=完整 --显示泄漏种类=所有 -v)
==13337== HEAP SUMMARY:
==13337== in use at exit: 72,724 bytes in 2 blocks
==13337== total heap usage: 7 allocs, 6 frees, 72,768 bytes allocated
==13337==
==13337== Searching for pointers to 2 not-freed blocks
==13337== Checked 123,368 bytes
==13337==
==13337== 20 bytes in 1 blocks are definitely lost in loss record 1 of 2
==13337== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13337== by 0x400A0A: get_divisors(int, int*) (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337== by 0x400964: main (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337==
==13337== 72,704 bytes in 1 blocks are still reachable in loss record 2 of 2
==13337== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13337== by 0x4E9B2AF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==13337== by 0x4010139: call_init.part.0 (dl-init.c:78)
==13337== by 0x4010222: call_init (dl-init.c:36)
==13337== by 0x4010222: _dl_init (dl-init.c:126)
==13337== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==13337==
==13337== LEAK SUMMARY:
==13337== definitely lost: 20 bytes in 1 blocks
==13337== indirectly lost: 0 bytes in 0 blocks
==13337== possibly lost: 0 bytes in 0 blocks
==13337== still reachable: 72,704 bytes in 1 blocks
==13337== suppressed: 0 bytes in 0 blocks
==13337==
==13337== ERROR SUMMARY: 7 errors from 3 contexts (suppressed: 0 from 0)
==13337==
==13337== 1 errors in context 1 of 3:
==13337== Invalid free() / delete / delete[] / realloc()
==13337== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13337== by 0x4009B7: main (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337== Address 0x5a37c80 is 0 bytes inside a block of size 4 free'd
==13337== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13337== by 0x400A0A: get_divisors(int, int*) (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337== by 0x400964: main (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337==
==13337==
==13337== 5 errors in context 2 of 3:
==13337== Invalid read of size 4
==13337== at 0x400985: main (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337== Address 0x5a37c80 is 0 bytes inside a block of size 4 free'd
==13337== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13337== by 0x400A0A: get_divisors(int, int*) (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337== by 0x400964: main (in /media/areuz/Storage - Linux/1 :: Documents/Programming/2 :: C++ Language/1 :: C++ Codes/Divisibility Check/divisibility)
==13337==
==13337== ERROR SUMMARY: 7 errors from 3 contexts (suppressed: 0 from 0)
问题:
在 get_divisor()
函数中,以下语句重新分配指针:
num_result = (int*)realloc(num_result, num_count*sizeof(int));
但num_result
是按值传递的参数,因此您只需更改此局部变量。 main 中的指针保持不变,因此,如果内存移动到另一个地址,您将在从函数返回后立即丢失重新分配的内存。
快速修复:
您可以通过引用传递指针,以便它实现您的预期方法(即原始指针确实在函数中被修改)。 只需更改函数签名/定义:
int get_divisors(int num_input, int *&num_result); // pass by reference
更好的方法:
首先,你应该真正摆脱 C++ 中的malloc()
和realloc()
:它们适用于基本类型,但不尊重更复杂对象(即未构造对象)的对象生命周期。
接下来,你不应该重新发明轮子。 与其管理自己一个可变大小的数组,不如选择向量:
vector<int> vnum_result(1); // initial size is one.
vnum_result.resize(num_count); // change the size
// no worries about freeing.
当然,通过引用或按值传递的问题仍然存在。
你应该习惯C++容器,不要害怕返回容器(查找返回值优化和复制省略):
#include <iostream>
#include <vector>
std::vector<int> get_divisors(int num_input)
{
std::vector<int> result;
for (int loop_1 = 1; loop_1 < num_input; loop_1++) {
if (num_input % loop_1 == 0) {
result.push_back(loop_1);
}
}
return result;
}
int main()
{
int num_input;
if(std::cin >> num_input) {
std::vector<int> divisors = get_divisors(num_input);
// You may consider a ranged base for: for (int divisor : divisors)
for (std::size_t loop_1 = 0; loop_1 < divisors.size(); loop_1++){
std::cout << divisors[loop_1] << "n";
}
}
}
相关文章:
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何增加以前由新运算符分配的 C++ std::list 数组的大小?
- 为模板参数类型中的新对象分配内存
- 新运算符分配的大小大于声明的大小.为什么
- 在C++中分配分配
- 为什么支撑初始化分配分配填充垃圾变量
- C 新操作员分配新内存
- 新不分配内存?
- 如果我的C++“新”内存分配失败,如何找出返回值
- 我可以用新的分配内存块吗?
- COM / DCOM:服务器存根不会为现有接口中的新方法分配内存
- 在线程在 C++ 中完成后将新任务分配给线程
- 只能使用CUDA中的新运算符分配有限的内存
- 与将新内容分配给向量的指针斗争
- 确定C++中新运算符分配的内存大小
- 按新内存分配
- 是否有必要使用 'new' 将新指针分配给与指向同一结构的先前存在的指针相同的结构?如果是这样,为什么?
- 用于新运算符分配的公共内存
- boost::io_service post方法是否引起新的分配?
- 如何在C++中检索由新运算符分配的对象的地址