이전에 필자는 필자가 작성한 파스칼 삼각형 프로그램에 대한 질문을하고 초기 문제를 수정했습니다. gmp로이 작업을 시도해 보니 새로운 문제가 생겼습니다! 나는 언어에 익숙하지 않으므로 나와 양육하십시오. 여기pascals 삼각형 모양의 c와 gmp
/*
This code is just to see exactly how much faster C is than python
at doing numerically stuff. It should calculate the nth row of
pascals triangle.
The way you use it is by calling the executable with the row
you wish to compute as the only argument. For example if you
are on an *nix system:
./pascal 6
Or in a windows command prompt:
pascal.exe 6
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <gmp.h>
/*
I decided to use a struct here because I thought it was ugly
to have to pass around the length of my arrays in function
calls.
*/
typedef struct{
int length; //length of the array
int numbits; //number of bits allocated per val in vals
mpz_t* vals; //pointer to start of array
} CoolArray;
//initArray allocates memory for the CoolArray.
void initArray(CoolArray* array, int length, int numbits);
//destroyArray frees allocated memory in the struct.
void destroyArray(CoolArray* array);
//printArray prints the contents of the array.
void printArray(CoolArray* array);
//pascal computes the nth row of pascal's
//triangle, with n being array->length,
//and stores the values in the array.
void pascal(CoolArray* array);
//setArray takes two CoolArrays of the same length
//and sets the values in the first to the values
//in the second.
void setArray(CoolArray* array1, CoolArray* array2);
int main(int argc, char** argv){
int length = atoi(argv[1]);
CoolArray array1;
initArray(&array1, length, 800); //giving every int 800 bits of memory
printf("Calculating the %dth row of pascals triangle...\n", length);
pascal(&array1);
printArray(&array1);
destroyArray(&array1);
return 0;
}
void initArray(CoolArray* array, int length, int numbits){
assert(length>=1); //don't make arrays with a length <=0!!!
array->length = length;
array->vals = (mpz_t*) calloc(length, sizeof(mpz_t)); //first I allocate memory for vals...
mpz_array_init(array->vals, length, numbits); //then I allocate memory for each val in vals
return;
}
void destroyArray(CoolArray* array){
int i=0;
for(; i < array->length; ++i){ //first I go through the array and
mpz_clear(array->vals[i]); //clear the memory used for each val
}
free(array->vals); //then use free on the entire array
return;
}
void pascal(CoolArray* array){
assert(array->length >= 1);//making sure the length wasn't fiddled with...
if(array->length == 1){
mpz_set_ui(array->vals[0], (unsigned long int)1);
return;
}
int row;
int index;
mpz_set_ui(array->vals[0], (unsigned long int)1); //if we aren't looking for the first row
mpz_set_ui(array->vals[1], (unsigned long int)1);//then i'll start with the second row
CoolArray current;
initArray(¤t, array->length, array->numbits); //current is a helper array
for(row = 2; row < array->length; ++row){
mpz_set_ui(current.vals[0], (unsigned long int)1); //set the first val to 1
for(index = 1; index < row; ++index){
mpz_add(current.vals[index], //set the value of this...
array->vals[index], //to this...
array->vals[index-1]); //plus this.
}
mpz_set_ui(current.vals[row], (unsigned long int)1); //make the last number 1
//printArray(¤t);
setArray(array, ¤t); //put every value in current into array
}
destroyArray(¤t); //get rid of current
return;
}
void setArray(CoolArray* array1, CoolArray* array2){
assert(array1->length==array2->length);//making sure they are the same length
int i=0;
for(; i < array2->length; ++i){
mpz_set(array1->vals[i], array2->vals[i]); //array1 is the array whose values are being set
}
return;
}
void printArray(CoolArray* array){
int i=0;
printf("[");
for(; i < array->length; ++i){
mpz_out_str(stdout, 10, array->vals[i]);
if(i < (array->length - 1)) printf(", ");
else printf("]\n");
}
return;
}
나는 정확한 출력을 얻고 있습니다. 값 인쇄는 정확하지만, 나는 또한 예상 출력과 함께 터미널에 다음과 같은 라인을 잔뜩 받고 있어요 :
gmpascal(80974) malloc: *** error for object 0x1008001a0: Non-aligned pointer being freed (2)
*** set a breakpoint in malloc_error_break to debug
나는 내 기능 destroyArray
잘못 메모리를 해제하고 있습니까? 그렇다면, 내가 아는 한 (gmp 매뉴얼을 점검하는 것으로부터) 정확하게 이것을하고 있기 때문에, 그것을 고칠 수 있을까? 또는 내 gmp 설치에 문제가 있습니까?
편집 : 좋아, 나는 내가 난 그냥 mpz_t 자체를 전달 되었어야 할 때, mpz_clear 내 mpz_t 배열의 각 요소에 대한 포인터를 전달했다 깨달았을 때 나는 큰 문제를 발견 생각했다. 나는 프로그램을 실행할 때 여전히 위의 결과를 얻는다.
gmpascal.c: In function ‘initArray’:
gmpascal.c:62: warning: passing argument 1 of ‘__gmpz_array_init’ from incompatible pointer type
이인가 :하지만 난 여전히이 컴파일러 경고를
이에서mpz_t array[length]; //length is an int
mpz_array_init(array, length, numbits); //and so is numbits
다른 :
mpz_t* array;
array = (mpz_t*) calloc(length, sizeof(mpz_t));
mpz_array_init(array, length, numbits);
?
첫 번째는 매뉴얼에서 직접 나온 예제이고 두 번째는 코드에서 어떻게 작성한 것입니까? 나는 그것이 문제일지도 모른다라고 생각한다. 그러나 나는 2가 다를 것 인 이유를 모른다.
감사합니다. 컴파일러가 경고 한 고정 된 한 가지가 있지만 여전히 malloc 오류가 발생했습니다. 나는 그 문제가 무엇인지 압니다. – Broseph