2016-10-13 18 views
0
#include<stdio.h> 
#include<stdlib.h> 
void func(char *p[],int); 
void main() 
{ 
    char **strings; 
    int r; 
    printf("\nEnter the no. of rows :"); 
    scanf("%d",&r); 
    strings=malloc(r*sizeof(strings)); 
    func(strings,r); 
    printf("%s %s\n", strings[0], strings[1]); 
} 

void func(char *p[],int r) 
{ 
    int i; 
    for(i=0;i<r;i++) 
     scanf("%s",p[i]); 
} 

このコードでは、3つの入力を受け取りません... 3つの入力の後、突然停止します。mallocが正しく動作していませんか?

mallocが正しく動作しないのはなぜですか?それはmallocのためだけですか?

+0

なぜC++としてタグ付けされていますか? – Slava

+2

質問を編集して、入力した正確な入力、得られた出力、予想した出力を追加できますか?コードがどのように機能するのかを理解する必要があります。 –

+2

成熟した言語としての親しみやすさと、Cとして間違ってしまうのは簡単です。「コンパイラが壊れています」というバリエーションは最後の手段です。おそらくそれはあなたのコードです。 – Schwern

答えて

4

問題は、あなたがmallocをどのように使用しているかにあります。あなたは十分なメモリを割り当てていないので、割り当てるメモリの量を知ることはできません。

strings=malloc(r*sizeof(strings)); 

これはr文字ポインタためstringsに十分なメモリを割り当てます。 stringsは、の変数rを安全に保存できるようになりました。問題はstringsに格納されている文字列にメモリを割り当てないことです。

void func(char *p[],int r) 
{ 
    int i; 
    for(i=0;i<r;i++) 
     /* At this point, p[i] is unallocated */ 
     scanf("%s",p[i]); 
} 

p[i]実際に文字列を格納するものも割り当てられなければならない。いくら?あなたが知っているのは、scanfを使って入力から読んでいるということです。だから、最初のカットは、固定サイズを割り当てて、そのサイズで読み込みます(ヌル文字のために1つしかない)。

void func(char *p[],int r) 
{ 
    int i; 
    for(i=0; i < r; i++) { 
     p[i] = malloc(256 * sizeof(char)); 
     scanf("%255s",p[i]); 
    } 
} 

最大長他入力はあなたが割り当てられたメモリよりも大きくすることができずにscanf %sを使用しないでください。またdon't use scanfの場合、入力があなたのパターンと一致しないと困ることがあります。必要に応じて、getlineまたはfgetsで全体の行を読み取ってからsscanfを読む方がよいでしょう。


Cでコーディングするときは、メモリチェッカーが絶対に必要です。これらの問題が発生します。私はvalgrindを使用します。

Enter the no. of rows :5 
foo 
==10082== Use of uninitialised value of size 8 
==10082== at 0x1001F2121: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib) 
==10082== by 0x1001EA979: scanf (in /usr/lib/system/libsystem_c.dylib) 
==10082== by 0x100000F2B: func (test.c:19) 
==10082== by 0x100000EBD: main (test.c:11) 
==10082== 
==10082== Invalid write of size 1 
==10082== at 0x1001F2121: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib) 
==10082== by 0x1001EA979: scanf (in /usr/lib/system/libsystem_c.dylib) 
==10082== by 0x100000F2B: func (test.c:19) 
==10082== by 0x100000EBD: main (test.c:11) 
==10082== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

これらはメモリの問題を指すスタックトレースです。 "サイズ8の初期化されていない値を使用すると"文字列にメモリを割り当てられなかったことがわかります。スタックはscanffuncであると私に伝えます。

+0

一時的な 'char'配列を作成して、各走査された' char * 'を' malloc'に各ポインタの長さ(nullの場合は+1)に格納するのはなぜですか?境界を超えて歩くことで一定のサイズと注意が必要ですが、これははるかに大きなスケールでメモリを節約するようです。 – duncan

+1

@duncanはい、行を読み込んで、おそらく非常に小さい内容を 'p'にコピーする' char行[256] 'を1つ持つことができます。 'getline()'はより良いものになり、 'line'を割り当てます。 – Schwern

+0

@schwern、なぜUはそこで256または255を特に使用しましたか? – shashank

関連する問題