2017-01-08 7 views
0

このプログラムを実行しようとすると、エラーmalloc()が発生します。 この関数からエラーが直接発​​生することはありません。この関数の後にmalloc()を実行しようとすると発生します。もし私が自由に行(ch)を削除すると正しく動作するので、私はそれを解放しようとすると破損が起こると思います。 main()は、この関数をどのように使用するかの例です。割り当てられた文字列を解放するときのメモリ破損

char * makeInt(int val){ 
    char *res = malloc(5); 
    char l [5] = ""; 
    sprintf(l,"%d",val); 
    if(val < 10){ 
    strcat(res,"000"); 
    strcat(res,l); 
    } 
    else if(val < 100){ 
    strcat(res,"00"); 
    strcat(res,l); 
    } 
    else if(val < 1000){ 
    strcat(res,"0"); 
    strcat(res,l); 
    } 
    else if(val < 10000){ 
    strcat(res,l); 
    } 
    res[4] = '\0'; 
    return res; 
} 


    char * makeString(char *ch){ 
    int t = strlen(ch); 
    char *chaine = malloc(t+4); 
    char *nb = makeInt(t); 
    strcat(chaine,nb); 
    strcat(chaine,ch); 
    chaine[t+4] = '\0'; 
    free(ch); 
    return chaine; 
} 

int main(){ 
    char *path = malloc(100); 
// here we do many operations on path, when i call makeString, path contains something 
     path = makeString(path); 
    } 

編集:申し訳ありませんが投稿したときに私はいくつかの情報を忘れてしまった。インクルードについて、私のコードにはありますが、インクルードされていないインクルードがコンパイル後にメモリ破損を起こすとは思わないでしょう。また、私はmakeString()を呼び出すとき、パスには文字列が含まれています。コード内の異なる場所でmakeString()を使用します。私は無料(チャネル)のエラーが表示されましたが、私はなぜメモリ破損の原因になるメモリをメインに割り当てられて解放するのか分からない追加が追加されました。

+3

'STRCAT(CHAINE、NB)は、' 'としてchaine'内容はまだ定義されていません。 'path'と同じです。 – chux

+0

makeString()では、makeString()が呼び出される前に初期化されていなかった "ch"の長さを調べようとしています...上記の@chuxのように、malloc()はそのメモリを初期化しませんあなたはそれをするか、代わりにcalloc()を呼び出す必要があります。 – TonyB

+0

投稿されたコードに '#include'文がないので、コンパイルされません。実際のコードに何が含まれているのか推測したくないのです。 – user3629249

答えて

0

掲載のコードは、例えば、特定の論理エラーが含まれています

strcat(chaine,nb); 

が、初期文字列はNULバイトを持たなければならない、そうでない場合は(IE未定義の動作)が返されますどのような値は不明である

malloc()からの戻り値は、最初の文字にNULバイトを持つこともあれば、持たないこともあります。

これはおそらく、投稿されたコードがsegaultイベントを引き起こしている理由です。

(あなたもcalloc()はなくmalloc()

を使用して、この特定の問題を解決することができ、makeString()へのパラメータはNULは、文字列を終了する任意の特定に初期化されていません。だから、strlen()

にそのパラメータを渡すために未定義の動作です

(最初に遭遇したNULバイトがうまく「パスの配列の終わりを超えて可能性があるため)

いくつかの提案:

  1. コードが使用するシステム関数のマニュアルページを参照してください。
  2. 実際に何が行われているかを確認するには、任意のコード(好ましくはデバッガを使用)を実行します。

ここには、あなたの役に立つコードのバージョンがあります。

#include <stdio.h> // printf(), sprintf() 
#include <stdlib.h> // malloc() 
#include <string.h> // strlen(), strcat() 

// prototypes 
char * makeString(char *ch); 


char * makeString(char *ch) 
{ 
    // EDIT: this line was wrong: char *chaine = malloc(sizeof(ch) + 7) // large enough to handle any int value 
    char *chaine = malloc(strlen(ch) + 7); 

    sprintf(chaine, "%4lu", strlen(ch)); 
    strcat(chaine, " "); 
    strcat(chaine, ch); 

    return chaine; // the caller must call `free()` 
} // end function: makeString 


int main(void) 
{ 
    char *path = "my path string"; 
    path = makeString(path); 
    printf("%s\n", path); 
    free(path); 
} // end function: main 

と出力される。

14 my path string 
+0

' char * chaine = malloc(sizeof(ch)+ 7); '間違っています。 – wildplasser

+1

あなたはmallocをどれくらい再考してください。ポインタのサイズはこれとは関係ありません。また、バッファオーバーフローを避けるために 'snprintf'を使うべきです(int値は7を超えることがあります)。 –

+0

' malloc() 'の呼び出しで問題を修正しました。 – user3629249

関連する問題