0

文を逆にするこの小さなプログラムを作成しました。与えられた:abcd

それは与えます: dcba

余分な文字を追加するまで、これは正常に機能します。「abcd e」を試すと、最後のエラーで失敗します

realloc(): 次のサイズが無効です: 0x0000000000602010 *

ここにコードがあります

#define MAX_TEXT 100

#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };    
    char *parts = NULL;

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    sscanf(text,"%[^\n]",text); //remove the \n


    char **reverse = NULL;
    char **extra = NULL;
    int size = 0;
    int i = 0;

    parts = strtok (text," ");
    while (parts != NULL) {

        size += ((strlen(parts)+4) * sizeof(char));
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

私はまだポインタへのポインタはもちろんのこと、ポインタを使用することに慣れていないので、どんな助けも素晴らしいでしょう. ありがとう!

Ps: valgrind を使用してみましたが、realloc に何か問題があることを示していますが、何が正確に理解できません。

更新されたコード:

#define MAX_TEXT 500

#include <stdio.h>
#include <string.h> //strchr
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };        

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    //sscanf(text,"%[^\n]",text); //remove the \n <-- Undefined behaviour :D "if copying takes place between objects that overlap, the behavior is undefined."
    char *theEnter = strchr(text,'\n');
    if (theEnter) {
        *theEnter = 0;//remove \n
    }        

    char **reverse = NULL;
    char **extra = NULL;
    char *parts = NULL;
    int size = 0;
    int i = 0;
    size_t increse_by = sizeof(char *);

    parts = strtok (text," ");
    while (parts != NULL) {

        size += increse_by; //pointer to pointer so increase by the size of new pointer
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

チャーリー・バーンズの指示に従って、現在 char * に割り当てています。また、sscanf 関数を削除し、strchr を使用して \n を削除しました。

助けてくれてありがとう :)

4

1 に答える 1

2

再割り当てで十分なスペースが割り当てられていません。sizeof(char *) はおそらくあなたのマシンでは 8 です。以下の realloc は、strlen == 1 の一部に (1 + 4) * 1 = 5 を割り当てます。文字列ポインターには十分ではありません。

変更してみる

    size += ((strlen(parts)+4) * sizeof(char));

    size += sizeof(char *);

extraその理由reverseは char ** です。したがって、それらは文字列へのポインターの配列です。strtokこの配列は、 ()をループするたびに 1 つ大きくなります。strtok() はヌル終了文字列を返します。したがって、そのためにメモリを割り当てる必要はありません。

この場合は必要ありませんが、次のこともできます。

reverse[i++] = strdup(parts);

の文字列が、それ自体の内部ではなくreverse、 の文字列のコピーを指すようにしたい場合。texttext

于 2013-10-18T15:38:48.123 に答える