2016-12-15 8 views
0

だから私は、私は私が持っているものは、端末での巨大な文字列を入力し、この配列内の文字列を保存することができるようにしたい端末からテキスト文字列にメモリを割り当てるにはどうすればよいですか?

typedef struct data_{ 
    char * path; 
} data; 

、私はchar型の配列を持つ構造体が、それはこのようになります持っています今試したのは、

data * data_ptr = malloc(sizeof(data)); 

data_ptr->path = malloc(sizeof(argv[i]) + 1); /*+ 1 to allocate an extra bit for I/O*/ 
strcpy(data->path, argv[i]); 

です。プログラムを終了する前に、私はメモリを解放します。しかし何らかの理由でセグメンテーション違反が発生する。私は自分のコードで2つの場所にメモリを割り当てていて、うまく動作しているようです。私はValgrindには新しく、問題があると言っていることを解読しようとしていますが、あまりにも理解しています。

==3117== Memcheck, a memory error detector 
==3117== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==3117== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==3117== Command: ./*** 
==3117== 
==3117== Syscall param open(filename) contains uninitialised byte(s) 
==3117== at 0x4F30460: __open_nocancel (syscall-template.S:84) 
==3117== by 0x4EB3ACD: _IO_file_open (fileops.c:221) 
==3117== by 0x4EB3D34: [email protected]@GLIBC_2.2.5 (fileops.c:328) 
==3117== by 0x4EA7D33: __fopen_internal (iofopen.c:86) 
==3117== by 0x400AF7: search_file (in /home/***) 
==3117== by 0x400BE5: main (in /home/***) 
==3117== Uninitialised value was created by a stack allocation 
==3117== at 0x400B8C: main (in /home/***) 
==3117== 
File does not exist. 
==3117== Conditional jump or move depends on uninitialised value(s) 
==3117== at 0x4C2EDA1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3117== by 0x400BF1: main (in /home/***) 
==3117== Uninitialised value was created by a stack allocation 
==3117== at 0x400B8C: main (in /home/***) 
==3117== 
==3117== Invalid free()/delete/delete[]/realloc() 
==3117== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3117== by 0x400BF1: main (in /home/***) 
==3117== Address 0x400770 is in the Text segment of /home/*** 
==3117== at 0x400770: _start (in /home/***) 
==3117== 
==3117== Conditional jump or move depends on uninitialised value(s) 
==3117== at 0x4C2EDA1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3117== by 0x400BFD: main (in /home/***) 
==3117== Uninitialised value was created by a stack allocation 
==3117== at 0x400B8C: main (in /home/***) 
==3117== 
==3117== Invalid free()/delete/delete[]/realloc() 
==3117== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3117== by 0x400BFD: main (in /home/***) 
==3117== Address 0xffefffeb0 is on thread 1's stack 
==3117== 
==3117== 
==3117== HEAP SUMMARY: 
==3117==  in use at exit: 24 bytes in 1 blocks 
==3117== total heap usage: 3 allocs, 4 frees, 1,600 bytes allocated 
==3117== 
==3117== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1 
==3117== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3117== by 0x400882: parse (in /home/***) 
==3117== by 0x400BC6: main (in /home/***) 
==3117== 
==3117== LEAK SUMMARY: 
==3117== definitely lost: 24 bytes in 1 blocks 
==3117== indirectly lost: 0 bytes in 0 blocks 
==3117==  possibly lost: 0 bytes in 0 blocks 
==3117== still reachable: 0 bytes in 0 blocks 
==3117==   suppressed: 0 bytes in 0 blocks 
==3117== 
==3117== For counts of detected and suppressed errors, rerun with: -v 
==3117== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) 

私は何が間違っているのか分かりますか?私がValgrindsのアウトプットを取るのは、私がアクセスできないメモリに到達しようとしているか、あるいは何か変わった方法でスタックを乱しているということです。しかし、私は正直であることを知らない。

+0

多分あなたはこれを必要とします: 'typedef struct data_ {char path [YOUR_MAX_PATH_LENGTH]; }データ; '。あなたの例では 'path'は配列ではなくポインタです。 –

+0

...とティックは[XY問題](http://xyproblem.info/)のように見えます。何を達成しようとしていますか? –

+0

これはXYの問題ではありません。私はちょうどメモリを割り当てようとしていて、どのように行っているのかを教えています。良い解決策を見つけ出すのが簡単だと思うなら、問題に – Salviati

答えて

0

使用STRLEN

data * data_ptr = malloc(sizeof(data)); 

data_ptr->path = malloc(strlen(argv[i])); 
strcpy(data->path, argv[i]); 

はsizeof(ARGV [i])というより私は私の値がARGCの範囲0内であることを願っ..

3

これ:

data_ptr->path = malloc(sizeof(argv[i]) + 1) 

が間違っている場合は、sizeofを使用して、実行時に文字列の長さを取得することはできません。あなたはstrlen()を使用する必要があります:あなたはそれを持っている場合は、割り当てとコピーの両方を行うためにstrdup()を使用することができます

data_ptr->path = malloc(strlen(argv[i]) + 1); 

。あなたはそのことを覚えておらず、+ 1を覚えています。

+0

それは助けに見えなかった、それはまだコンパイルされますが、セグメンテーションの失敗は残っており、valgrindはまだ私に叫ぶ。私はちょうどもう一度コードを通過しなければならない。もうすぐ戻ってきます。編集:それは動作しない理由の1つの平和されている必要がありますが、私も間違った何かをしている必要があります – Salviati

+0

これは本当に "助け"、前にしていたものが間違っていたと4つ以上の文字。 – unwind

+0

私は同意しますが、それでもうまくいかないので、私は他のどこかで間違ったことを行っているかもしれないと思います。 – Salviati

1

argv[i]は、ポインタの文字列ですが、文字列自体は含まれません。したがって、sizeof(argv[i])を実行すると、ポインターのサイズのみが取得され、ポインターのサイズは取得されません。

malloc(sizeof(argv[i]) + 1)を実行すると、5または9バイト(ポインタのサイズに応じて、通常は32ビットシステムでは4バイト、64ビットシステムでは8バイト)だけが割り当てられます。

文字列の長さを取得するには、strlenを使用する必要があります。

0

sizeofを使用することはできませんが、mallocを実行するときはstrlenを使用する必要があります。

しかし、valgrindは何が間違っているのかを伝えています。存在しないファイルを開こうとしています。

==3117== Syscall param open(filename) contains uninitialised byte(s) 
==3117== at 0x4F30460: __open_nocancel (syscall-template.S:84) 
==3117== by 0x4EB3ACD: _IO_file_open (fileops.c:221) 
==3117== by 0x4EB3D34: [email protected]@GLIBC_2.2.5 (fileops.c:328) 
==3117== by 0x4EA7D33: __fopen_internal (iofopen.c:86) 
==3117== by 0x400AF7: search_file (in /home/***) 
==3117== by 0x400BE5: main (in /home/***) 
==3117== Uninitialised value was created by a stack allocation 
==3117== at 0x400B8C: main (in /home/***) 
==3117== 
File does not exist. 

だから、おそらくあなたが偽のファイルを開こうとしている(すなわち filenameの値が偽であるか、それだけでゴミデータですか)?または、偽のデータを fopenに渡していますか? fopenに渡すパスは何ですか?

+0

ファイルが存在し、Im shureです。すべてのメモリコードを実行する前に、私はすべての古いコードをコピーしました。何も動作しなければ、私は簡単に戻ることができました。私が古いコードを使用している場合、それは動作しています。新しいものを使用する場合、それは機能していません。私は同じものを同じものと呼んでいます。 – Salviati

+0

だから、あなたはfopenに渡す文字列の内容は何ですか? printfを使ってターミナルで見るか、gdbを使って何が入っているのかを調べることができます。 – cigarman

関連する問題