我希望创建一个函数,它返回一个数字可以除以的所有可能数字。另外,我希望在另一个函数中使用这些返回的结果,这些函数查找这些结果中的所有素数,然后返回那些。
长话短说,我希望能够返回“动态数组”并在另一个函数中再次使用它们。
到目前为止我所拥有的:
int *division (long a) {
int i;
int *divResult = malloc(a * sizeof(long)); //Ultimately I want to allocate space dynamically instead of reserving too much space
if (naturalNumber(a)) { //What it basically does is "fmod(a, 1)" (returns boolean)
divLength = 0; //A global int set to trace the length of division()
for (i = 0; i < a + 1; i++) {
if (divisor(i, a)) { //Checks wether the division of a by i returns a whole number (returns boolean)
//divResult = realloc(divResult, sizeof(long)); //This gives seg faults and errors durning runtime; To be clear I am not exactly using it like this. What I do is I adjust the "malloc(a*sizeof(long))" to "malloc(sizeof(long))"
divResult[i] = i; //If i is a divisor add it to the pointer
divLength += 1; //track how long the current division is
}
}
}
free(divResult); //I was hoping this to remove the divResult from the memory, sadly it is still there and doesnt give me an error of me trying to return a NULL value
//printf("Mem: %p\n", (void *)divResult);
return divResult; //Return a "dynamic array" so that another function can use it
}
正如您所看到的,我知道我必须使用指针而不是真正的数组,因为这些指针无法返回。 我知道这有效并且已经恢复了真正的价值。
此外,我希望此函数使用division()函数来查看数字的除数并将它们放在数组中:
int *primes (long a) { //I'm trying to reuse the same tactic as before:
int i;
int *primeResult = malloc(a * sizeof(long)); //Allocating it again...
if (naturalNumber(a)) { //See previous codeblock
for (i = 0; i < a + 1; i++) {
division(i); //Calling the function here to divide each number from 1 to "a" so I am able to see which one is of size 2 (in other words the division of number *1 to a* and check wether it is a prime number (it has in total only 2 divisors))
printf("len = %d\n", divLength); //prints the current length of division()
if (divLength == 2) { //If the division() "length" is 2
primeResult[i] = i; //add i to primes
}
}
}
free(primeResult); //Same as above
return primeResult;
}
你可能猜到我没有得到预期的结果。
使用:
int *div;
div = division(a) + 1;
for (i = 0; i < a; i++) {
if (*(div + i) != 0)
printf("*(div + %d) : %d\n", i, *(div + i));
}
int *prime;
prime = primes(a) + 1;
for (i = 0; i < a; i++) {
if (*(prime + i) != 0)
printf("*(prime + %d) : %d\n", i, *(prime + i));
}
我明白了:
len = 6
len = 1
len = 2
len = 2
len = 3
len = 2
len = 4
len = 2
len = 4
len = 3
len = 4
len = 2
len = 6
*(prime + 1) : 2
*(prime + 2) : 3
*(prime + 3) : 4
*(prime + 4) : 5
*(prime + 5) : 6
*(prime + 6) : 7
*(prime + 10) : 11
*(prime + 11) : 12
我可以向你保证,如果我注释掉除除了()和调用primes()之外的所有痕迹,我仍然可以得到结果:
*(div + 1) : 2
*(div + 2) : 3
*(div + 3) : 4
*(div + 5) : 6
*(div + 11) : 12
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
len = 0
*(prime + 1) : 2
*(prime + 2) : 3
*(prime + 3) : 4
*(prime + 5) : 6
*(prime + 11) : 12
所以,我知道我的代码很糟糕;这就是为什么我现在要问(我还在学习),我问你:
最后但并非最不重要的是:有没有人真正理解我在问什么?
答案 0 :(得分:3)
释放指针时,分配给它的内存会发生什么变化是未定义的。它不会被清除,可能会重复使用,内存的内容可能会被覆盖......或者可能没有。
在你的情况下,从你释放它的那一刻到你打印它的那一刻之间,内存似乎保持不变,但在每次执行你的程序或每个操作系统时都可能不是这样。
void* realloc (void* ptr, size_t size)
将复制在ptr
分配的内存,并将其复制到大小为size
的新内存区域。但是你用realloc
来实现什么呢?
有没有更简单的方法在单独的功能中完成所有这些? 你能更具体一点吗?
更新(评论时): 你可以重构你的两个函数来拥有相同类型的接口,但是可以在不同的上下文中使用以下原型:
// the functions take as a parameter an array of integers, an a pointer to an integer. It returns an array of transformed data and through the second parameter, the length of the output.
int* findDividers(int input, int* output_length) {
int* dividers = malloc(input * sizeof(int));
int found_dividers = 0;
// do things
int* tmp = realloc(dividers, found_dividers);
free(dividers);
*output_length = found_dividers;
return tmp;
}
int* primeFilter(int* input, int input_length, int* output_length) { /* same structure as before */ }
// you can then use it as follow
int integer_to_process = 0xdeadbeef;
int dividers_count = 0;
int* dividers = findDividers(integer_to_process, ÷rs_count);
int primes_count = 0;
int* primes = primeFilter(dividers, dividers_count, &prime_count);
// now feel free to use the two arrays, with a minimal length, as you want.
答案 1 :(得分:2)
为什么它仍然会返回division()的值,即使我已经“释放”了divResult的内存?访问释放的内存块的内容是未定义的行为,任何事情都可能发生。在大多数实现中,如果内存未被重用于其他任何内容,您将能够看到旧值。但是你不能依赖它,因为你不知道什么时候会重新分配内存。
如何让realloc()工作?如果仍然需要,请不要释放内存。只要分配了内存,就可以使用realloc()
缩小或扩展内存。但请确保更新所有指向内存的指针,因为realloc()
可以移动内存。
有没有更简单的方法在单独的功能中完成所有这些?这是一个非常广泛的问题。
答案 2 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
long *division(long n){
int i, len = 1;//for 1
long *result;
if(n < 1) return NULL;
result = malloc(n * sizeof(long));
if(result){
for (i = 2; i <= n; ++i)//skip 1
if(n % i == 0)
result[len++] = i;
result[0] = len;//put a length instead of 1
result=realloc(result, len*sizeof(long));
}
return result;
}
long *factor(long n){
int i=2, sqi=4, len = 1;
long *result;
if(n < 1) return NULL;
result = malloc((n/2+1)*sizeof(long));
if(result){
while(sqi <= n){
int flag = 0;
while(n % i == 0 && (flag = 1))
n /= i;
if(flag)
result[len++] = i;
sqi += 2*(i++) + 1;
}
if(n != 1)result[len++] = n;
result[0] = len;
result=realloc(result, len*sizeof(long));
}
return result;
}
long *primes(long n) {Quite verbose
int i, len = 1;
long *result;
if(n < 1) return NULL;
result = malloc((n/2+2) * sizeof(long));
if(result){
for (i = 2; i <= n; ++i) {
long *div=factor(i);
if(div[1] == i) {
result[len++] = i;
}
free(div);
}
result[0] = len;
result=realloc(result, len*sizeof(long));
}
return result;
}
int main(){
long *div = division(1234);
int i, len = div[0];
for(i=1;i<len;++i){
printf("%ld\n", div[i]);
}
free(div);
printf("\n");
long *fact = factor(123456);
len = fact[0];
for(i=1;i<len;++i){
printf("%ld\n", fact[i]);
}
free(fact);
printf("\n");
long *prime = primes(123);
len = prime[0];
for(i=1;i<len;++i){
printf("%ld ", prime[i]);
}
free(prime);
printf("\n");
return 0;
}