2012-02-03 6 views
0

私は統計パッケージ用のコードを書いています。データをポインタ配列に読み込むことから始めます。私はポインタを初期化し、mallocを使って十分なメモリを割り当てます。しかし、私はときどき、以下のコードの最後にあるメモリ割り当てにエラーが発生します。メモリ割り当てエラー - Linuxでは、しかしOSX Unixではありません。

#include <stddef.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "stats.h" 

int main(int argc, char **argv) { 
FILE *fp, *outFile, *outBin; // create a file identifier 
size_t n, nbins; // # of data points 
double *data; // pointer to hold data 
double average, variance, *med; // stat returns 
int medianComplete, histComplete, i; // return 1 on success 
hist_t *Histogram; 

// read in the number of bins from exe arguments 
nbins = atoi(argv[1]); 
nbins = (size_t)nbins; 

// open the binary datafile and read in first value 
// which is number of data points 
// use exe input for filename 
fp = fopen(argv[2],"rb"); 
fread(&n, sizeof(size_t),1,fp); 

// allocate enough memory to hold all data 
data = (double*)malloc(sizeof(double)*n); 
if (!data) 
    printf("Memory allocation error"); 
fread(data,sizeof(double),n,fp); 

このプログラムは、コンパイルと私の個人的なマシン(MacOSXの)上でも動作しますが、私はLinuxサーバ上でそれを実行しようとすると、セグメンテーションエラーによる失敗します。 Valgrindを使用して、エラーを追跡できるかどうかを確認し、次の結果が得られました。

==8641== Warning: silly arg (-501426814648844128) to malloc() 
==8641== Invalid write of size 1 
==8641== at 0x4C2B20D: mempcpy (mc_replace_strmem.c:956) 
==8641== by 0x4EA2F15: _IO_file_xsgetn (fileops.c:1423) 
==8641== by 0x4E971D2: fread (iofread.c:44) 
==8641== by 0x40086D: main (runstats.c:28) 
==8641== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

これは、ポインタを使用して、私が今までに書いた最初のプログラムである、と私はそれが一つのシステムが、他のではない上で動作する理由のために途方に暮れてよ。

+0

を追加しました、とのfopen()が成功しています。 Valgrindは、データをメモリに割り当てるときにエラーが発生したことを示します。私がデータに対して実行するチェックはサーバ上で失敗しますが、自分のコンピュータ上で実行されます。 – dwv5009

+0

質問が表示されたときに最初に現れるのは、「なぜC言語で何十もの適切な言語が存在するときに、これをやっているのですか?」 – vines

答えて

5

sizeof(size_t)はプラットフォームによって異なります。デフォルトの32ビットコードのOSXでは、size_tは4バイトです。 64ビットLinuxでは、size_tは8バイトです。 64ビットLinuxで実行している場合は、32ビットOSXで読んでいる別のnを読んでいます。

バイナリデータ形式を使用する必要がある場合は、プラットフォーム固有の種類のサイズをフィールドサイズとして使用しないでください。ファイルヘッダーが4バイトか8バイトか、リトルエンディアンかビッグエンディアンかを決定し、それを一貫して使用します。

参照:ファイルポインタのテストで What's sizeof(size_t) on 32-bit vs the various 64-bit data models?

+0

Ah!もちろん。それがそのバグを解決しました。ありがとう! 私がValgrindから得ているエラーは次のとおりです。 "初期化されていない値がスタック割り当てによって作成されました"が私の主な宣言を指しています。 – dwv5009

+0

あなたは 'fread'で' size_t'にまだ読んでいますか? 4バイトを読んでいるなら、 'fread'を' stdint.h'の 'uint32_t'に使うことを検討してください。 –

2

あなたは間違いなく

デバッガを使用するか、fread(&n, sizeof(size_t),1,fp);を実行した後、nの値をprintfの...前の投稿へのあなたのソースをフォーマットする必要があります。あなたが期待した価値を得られないようだ。

+0

書式は残念です。 私はこれをチェックしました、n = 20は期待どおりです。 – dwv5009

+0

@ dwv5009 Valgrindはあなたが投稿したコードがvalgrindが不平を言っていると仮定して、そうではないと言います。 'fread(&n、sizeof(size_t)、1、fp);'の呼び出し直後に 'printf(" n =%zu \ n "、n); – nos

+0

@nosはい、私はそれを正確に行いました。結果は「n = 20」です。 以下の答えは、入力ファイルが32ビットシステム(4バイト)でsize_tを使用して書き込まれ、64ビットシステムで読み込もうとしたときに、size_tが入力ファイルのサイズが正しくありませんでした。 – dwv5009

関連する問題