2
早些時候,我問了一個關於我寫的帕斯卡三角形程序的問題,並且解決了我最初的問題。我現在有新的問題,我已經嘗試用gmp做這個!我對這門語言很陌生,所以請和我一起裸照。這裏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;
}
我得到正確的輸出,sorta。值打印是正確的,但我也越來越一堆線條像這樣在終端與預期輸出一起:
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);
?
第一個是直接來自手冊的例子,第二個是我在代碼中寫的。我認爲這可能是問題,但我不知道爲什麼兩者會有所不同。
謝謝,這固定了編譯器警告過我的一件事,但我仍然遇到了大量出現malloc錯誤的東西。我想我知道問題是什麼。 – Broseph