0

統計パッケージのコードを書いています。まず、データをポインター配列に読み込みます。ポインタを初期化し、mallocを使用して十分なメモリを割り当てます。ただし、以下のコードの最後でメモリ割り当てでエラーが発生することがあります。

#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

これは、ポインターを使用する私がこれまでに作成した最初のプログラムであり、一方のシステムでは機能するが、もう一方のシステムでは機能しない理由に戸惑っています。

4

2 に答える 2

5

sizeof(size_t)プラットフォームに依存します。デフォルトの32ビットコードのOSXでは、size_t4バイトです。64ビットLinuxでは、size_t8バイトです。64ビットLinuxで実行しているn場合は、32ビットOSXで読んでいるものとは異なるものを読んでいます。

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

参照: 32ビットとさまざまな64ビットデータモデルのsizeof(size_t)は何ですか?

于 2012-02-03T08:32:44.970 に答える
2

投稿する前に、必ずソースをフォーマットする必要があります...

デバッガーを使用するか、実行後にnの値をprintfしますfread(&n, sizeof(size_t),1,fp);。期待した値が得られないようです。

于 2012-02-03T08:07:40.757 に答える