0

以下のように文字列を取得する %s を含む malloc と scanf を使用した以下の単純なプログラムでは、理解できない出力が得られます。私は 5 バイトしか「malloced」していませんが、入力文字列は上記のサイズを超えていますが、セグメンテーション違反はありません。scanf は malloc 割り当てを上書きしていますか?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  char * name;
  int SZSTRING;

    printf("Enter size of name :");  
    scanf("%d", &SZSTRING);
    name = (char*) malloc ((SZSTRING + 1) * sizeof(char));

    printf("Enter name :");
    scanf("%s", name);
    printf("len of 'name' : %d\n",strlen(name));

  printf("name final: \"%s\"\n",name);
  free(name);

return 0;
}

Output:

OptiPlex-380:~/gsa/compile$ gcc -o try try.c 
OptiPlex-380:~/gsa/compile$ ./try 
Enter size of name :4
Enter name :qwertyui
len of 'name' : 8
name final: "qwertyui"

ここでもう 1 つ気付きました。

    //scanf("%s", name);

出力ショー

len of 'name'= 0

「malloced」の場所は、実際には NULL に memset されていました。しかし、man-page に従って割り当てられたバイトを 0 に初期化する malloc ではなく calloc ???

4

3 に答える 3

2

それは「うまくいく」ように見えるかもしれませんが、それはあなたが幸運になったからです。あるコンパイラでコードを実行すると、別のコンパイラで「動作」し、ヒープが破損したためにクラッシュします。使用する場合の最善の策scanf()は、scanf()がメモリを割り当てることを許可することです。

scanf("%ms", &name); // compiled with -std=c99 this will allocate the correct amount
                    // of memory for you. You can use "%as" if you're using -std=c89 

また、には戻り値(正常に一致して割り当てられた入力項目の数を示します)があることを覚えておいてscanf()ください。それが機能したかどうかを確認することが重要です。

グッドプラクティスを実施している間は、の戻り値を型キャストしないでください。malloc()

を使用しない別の方法は、代わりscanf()に使用することです。fgets()

fgets( name, SZSTRING, stdin);
于 2013-01-24T12:22:12.140 に答える
2

いいえ、そうではありません。ただし、割り当てられたバッファーのサイズを超えても、すぐにセグメンテーション違反が発生するとは限りません。領域が破損し、効果が後で表示されるか、まったく表示されないことがあります。

于 2013-01-24T12:14:02.393 に答える
1

このような場合は、セグメンテーション違反なしで実行される可能性があります。この場合、それはあなたが主張していないスペースを使用しているということであり、「誰か」が所有している可能性のあるいくつかのメモリ位置を破壊します。

于 2013-01-24T12:26:34.477 に答える