1

学生の名前とスコアを配列に入力し、同じ情報を画面に出力するシステムの作成に取り組んでいますが、残念ながら奇妙な出力が得られます。

デバッガーを使用してプログラムをステップ実行したところ、学生の情報を出力する関数に到達するまで、すべてがスムーズに実行されることが示されました。そこでは、二重ポインターの char 配列がめちゃくちゃな値を持っています。

これは、プログラムを実行したときに表示されるイメージです。( http://s28.postimg.org/nv29feawt/Error.png )

注: これを行うためのより適切で簡単な方法があることは承知していますが、動的に割り当てられたメモリと配列を使用してこの割り当てを完了する必要があります。

int main(void)
{
    char **firstNames;
    char **lastNames;
    float *scores;

    int recordsLength;
    printf("Please indicate the number of records you want to enter: ");
    scanf("%d", &recordsLength);
    printf("\n\n");

    firstNames = (char **)malloc(recordsLength * sizeof(char *));
    lastNames = (char **)malloc(recordsLength * sizeof(char *));
    scores = (float *)malloc(recordsLength * sizeof(float));

    int i = 0;
    while(i < recordsLength)
    {
        createNewEntry(i, firstNames, lastNames, scores);
        i++;
    }

    printEntry(0, firstNames, lastNames, scores);
    free(firstNames);
    free(lastNames);
    free(scores);
    return 0;
}

void clearScreen()
{
#ifdef _WIN32 
    system("cls");
#elif _unix_ 
    system("clear");
#endif
}

void printEntry(int entryID, char *firstNames[], char *lastNames[], float scores[])
{
    clearScreen();
    printf("|-------------------------------------------------------------------------|\n");
    printf("|                           Student Entry                                 |\n");
    printf("|-------------------------------------------------------------------------|\n|\n");
    printf("|   First Name: %s   Last Name: %s   Score: %.1f\n|\n|\n|\n", firstNames[entryID], lastNames[entryID], scores[entryID]);
    printf("|-------------------------------------------------------------------------|\n");
    printf("|                                                                         |\n");
    printf("|-------------------------------------------------------------------------|\n\n");
}

void createNewEntry(int index, char *firstNames[], char *lastNames[], float scores[])
{
    printf("Please input the records of the new student.\n\n\n");
    char first[20];
    char last[20];
    float score = 100.0f;

    printf("Please enter the student's first name: ");
    scanf("%s", &first);
    printf("\n\n");

    printf("Please enter the student's last name: ");
    scanf("%s", &last);
    printf("\n\n");

    printf("Please enter the student's score: ");
    scanf("%f", &score);
    printf("\n\n");

    firstNames[index] = (char *)malloc((strlen(first)) * sizeof(char));
    firstNames[index] = first;

    lastNames[index] = (char *)malloc((strlen(last)) * sizeof(char));
    lastNames[index] = last;
    printf("first name: %s", firstNames[index]);
    printf("last name: %s", lastNames[index]);
    scores[index] = score;
}
4

2 に答える 2

1
firstNames[index] = (char *)malloc((strlen(first)) * sizeof(char));
firstNames[index] = first;  /* You are missing your allocated memory block and assigning local */

上記の行は正しくありません。代入演算子c-stringsでは代入できません。=そのために使うべきstrcpyです。

関数が終了した後は寿命がありません。これにより、未定義の動作が発生します。(奇妙な文字が表示されますが、さらに悪化する可能性があります)。

と書き換える必要があります(姓も同様)

firstNames[index] = malloc((strlen(first) + 1) * sizeof(char)); /* +1 for \0 */
if(firstNames[index] == NULL) {
  /* Malloc failed, error handling */
  ...
}
/* else */
strcpy(firstNames[index], first);  /* Use strcpy to copy contents */

実例はこちら

firstNamesとを解放する前にlastNames、firstNames と lastNames のすべてのメンバーをループで解放する必要があります。

于 2014-11-14T06:00:38.093 に答える