0

strtok と動的配列を使用して分割関数を作成しようとしています。ただし、どこで問題が発生しているのかわかりません。有益なエラー メッセージはありません。セグメンテーション違反とは言いますが、ヒープがどのように壊れているか、またはその原因が何であるかはわかりません。誰かが私に何が間違っていて、それを正しく行う方法を喜んで説明してくれますか?

11:16 CST コードを編集:

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

char **toArray(char **array, char str[], char sep[], int *count);
char** my_split(const char* str, char delim, int* size);

int main(int argc, char* argv[]) {
    char* test = "Hello there lol";
    int *count = 0;
    char **array = malloc(sizeof(char*) * 5);
    toArray(array, test, " ", count);
    printf("Count: %d\n", *count);

    int array_i;
    for (array_i = 0; array_i < *count; array_i++) {
        printf("array %d: %s\n", array_i, array[array_i]);
        free(array[array_i]);
    }
    free(array);
    return 1;
}

char **toArray(char **array, char str[], char sep[], int *count) {
    char *temp = str;
    temp = strtok(temp, sep);
    array[0] = temp;
    *count = 1;
    while ((temp = strtok(NULL, sep)) != NULL ) {
        array[(*count)++] = temp;
    }
    return array;
}
4

2 に答える 2

2

コンパイラ メッセージは私たちの友達です。私はあなたの問題を追跡するためにそれらを簡単に使用しました。 次のことを試して、実行したことと実行したことを比較してください。デカルレーションとポインター変数の使用に特に注意してください... :)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char **toArray(char **array, char str[], char sep[], int *count);

int main(int argc, char* argv[]) {
    char test[] = "Hello there lol";
    int count = 0;
    char **array = malloc((sizeof(char*) * 5) +1); //added "+ 1" here, read why
    toArray(array, test, " ", &count);             //in comment below
    printf("Count: %d\n", count);

    int array_i;
    for (array_i = 0; array_i < count; array_i++) {
        printf("array %d: %s\n", array_i, array[array_i]);
        //free(array[array_i]);
    }
    getchar();
    free(array);
    return 1;
}

char **toArray(char **array, char str[], char sep[], int *count) {
    char *temp = str;
    temp = strtok(temp, sep);
    array[0] = temp;
    *count = 1;
    while ((temp = strtok(NULL, sep)) != NULL) {
        array[(*count)++] = temp;
    }
    return array;
}

[編集]出力例:
ここに画像の説明を入力

また。 「hello」は実際には 5 文字と NULL 文字であるためこの行char **array = malloc(sizeof(char*) * 5);が必要でした 。 char **array = malloc(sizeof(char*) * 5 + 1);'\0'

C の string(s)に関するいくつかの経験則

1) malloc または calloc を使用する場合は、忘れずに'\0'.

     `char *buf1;` //buffer needed to manipulate buf2  
     `char  buf2[]="someString";`  
     `buf1 = malloc(strlen(buf2)+1);` or `buf1 = malloc(sizeof(buf2));`    
                                         (note:, no '+1'.  see '4)' below. ) 

2)使用する前に、新しく割り当てられた変数をクリア (初期化) します。例えば:

memset(buf, 0, strlen("someString")+1);  //preferred, all bytes are zeroed

また

buf[0]=0;  //useful, but use with care (only first byte is zeroed.)  

3)使用が終了したら、動的に割り当てられたすべてのメモリを解放します。例えば:

free(buf);   

4)strlen()関数またはsizeof()マクロの使用。(どちらも での使用に人気があります[mc]alloc())
指定:
char *buf1 ="Hello"; //6文字 |H|e|l|l|o|\0|
char buf2[] ="こんにちは"; //6文字 |H|e|l|l|o|\0|
char buf3[5]="こんにちは"; //5 文字 |H|e|l|l|o|
char buf4[5]="Hel"; //4 文字 |H|e|l|\0| |
char buf5[5]="Helloo";// コンパイル エラーが発生するはずです。初期化子が多すぎます

結果の比較strlen() - sizeof():

strlen(buf1); //->5("Hello\0" を保持するために必要な新しい変数の malloc に +1 が必要です)
sizeof(buf1); //->4(文字列の # chars ではなく、sizof (char *) を返します)

strlen(buf2); //->5(「Hello\0」を保持する必要がある新しい変数の malloc に +1 が必要です)
sizeof(buf2); //->6(「\0」を含むすべての文字をカウントします)

strlen(buf3); //-> (エラー: 文字列引数に終端の NULL がありません)
sizeof(buf3); //->5(すべての文字を数えますが、この文字列には '\0' がありません - 間違っています!)

strlen(buf4); //->3(文字をカウントしますが、'\0' はカウントしません)
sizeof(buf4); //->5('\0' を含むすべての割り当てられたスペースをカウントします)

于 2013-10-13T04:20:11.327 に答える
2

あなたはchar *test = "Hello there lol";あなたのtoArray(). 残念ながら、文字列は変更できないため、 で変更しようとするとstrtok()、セグメンテーション エラーが発生します。

最も簡単な修正は次のとおりです。

char test[] = "Hello there lol";

次のものもあります。

int *count = 0;

そして、次のように関数を呼び出します:

toArray(array, test, " ", count);

整数が必要で、そのアドレスを渡すには:

int count = 0;
...
toArray(array, test, " ", &count);

の要素が指す文字列も解放しようとしましたarrayが、それらは割り当てられませんでした (文字列の一部ですtest)。malloc()et al.で割り当てられていないものを解放しないでください。

これらの修正を行うと、次のコードが機能します。

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

char **toArray(char **array, char str[], char sep[], int *count);

int main(void)
{
    char test[] = "Hello there lol";
    int count = 0;
    char **array = malloc(sizeof(char *) * 5);

    toArray(array, test, " ", &count);
    printf("Count: %d\n", count);

    for (int i = 0; i < count; i++)
        printf("array %d: %s\n", i, array[i]);
    free(array);
    return 0;
}

char **toArray(char **array, char str[], char sep[], int *count)
{
    char *temp = str;
    temp = strtok(temp, sep);
    array[0] = temp;
    *count = 1;
    while ((temp = strtok(NULL, sep)) != NULL)
        array[(*count)++] = temp;
    return array;
}

出力:

Count: 3
array 0: Hello
array 1: there
array 2: lol
于 2013-10-13T04:26:29.513 に答える