为了保持代码整洁(并且过于复杂,正如我总是那样),我希望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;
}
Valgrind :( - leak-check = full --show-leak-kinds = all -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)
答案 0 :(得分:2)
<强>问题:强>
在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()
:这些与基本类型配合良好,但不尊重更复杂对象的对象生命周期(即不构造对象) 。
接下来,你不应该重新发明轮子。不要自己管理一个可变大小的数组,而是转到vectors:
vector<int> vnum_result(1); // initial size is one.
vnum_result.resize(num_count); // change the size
// no worries about freeing.
当然,通过引用或按值传递的问题仍然存在。
答案 1 :(得分:1)
你应该习惯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";
}
}
}