0

実行時に添付されている以下のCコードでエラーが発生します

summary: malloc.c:3074: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

malloc(21)のすべての呼び出しで; (下記参照)。誰かが理由を説明できますか?私は考えられるすべてのことを試しましたが、それでも失敗します。

ファイル:summary.c

/* 
* File:   summary.c
* Author: Maxim Veksler
*
* Created on December 4, 2009, 3:09 AM
*/

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

/*
* Main for Maman 12, task 1 : Array summary utility
*/
int main(int argc, char** argv) {
    /*STUB*/
    char str[100];
    strcpy(str, "3 5 234 11 77 44 5");
    /*STUB*/

    int resultsSize;
    int* results;
    int* aggregated;

    results = parseInput(str, &resultsSize);
    aggregatedArray((int*)NULL, (int)NULL);


    return 0;
}

ファイルmanipulation.c

    /*
    * File:   manipulation.c
    * Author: Maxim Veksler
    *
    * Created on December 4, 2009, 3:09 AM
    */

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

    /*
    * Parse the input from user, dynamically allocate memory to the maximum
    * possible requirment. Then convert the array of string tokens into an
    * simple array of integers.
    */
    int* parseInput(char* input, int* nOfResults) {
        /* Allocate memory by the maximum possibly required size for int... */
        int *results = (int*) malloc(strlen(input));

        int* insertIterator = results;
        char* pch;


        /* We trash the user input, but it's cool - Worthless as usual. */
        pch = strtok(input,"\t ,.-");
        *nOfResults = 0;

        while(pch != NULL) {
        (*nOfResults)++;

        *insertIterator = atoi(pch);
        insertIterator++;
        pch = strtok(NULL, "\t ,.-");
        }

        return results;
    }


    /*
    * Summary the values given in the int array and return adress to new array
    * containing an increasin sum of the values.
    */
    int* aggregatedArray(int* inputArray, int size) {
        int* results;
        malloc(20);
        malloc(21);
    }

編集このコードは、問題を示すためにここに表示される簡略化されたバージョンであることを考慮に入れてください。関連性のない部分をすべて削除しました。

4

3 に答える 3

5

編集:すごい、コードにかなり悪い論理エラーがあることに気づきました。これは単にリークしているだけでなく、バ​​ッファオーバーフローもあります!

int *results = (int*) malloc(strlen(input));

これにより、 18バイト(入力の長さ)が割り当てられint、それを'sの配列のように扱います。つまり、sをその中に収めることができます18 / sizeof(int) int。通常のx86サイズを想定すると、(18/4)== 4.5整数しか適合できないことを意味します!後で、コードはそれよりもいくつかを配列に書き込みます。大きなエラー。

この問題を修正するには、を使用する必要がありますrealloc。このようなもの:

int *results = malloc(sizeof(int));
int result_size = 1;
int result_count = 0;

while(/*whatever*/) {
    /* ok, i want to add an element to results */
    if(result_count == result_size - 1) {
        int *p = realloc(results, (result_size + 1) * sizeof(int));
        if(!p) {
            free(results);
            return NULL; /* no more memory! */
        }
        results = p;
        result_size++;
    }
    results[result_count++] = /*value*/
}
return results;

mallocどこにも結果を保存していない2秒があるのでリークします。これによりfree、これらの呼び出しが返すポインターを参照できなくなります。

実際、実際に何をしているのかはわかりませんaggregatedArray、現時点ではリークしているだけです。

また、edポインタを返すresults = parseInput(str, &resultsSize);whereがあります。後でこれが不要になったとき(おそらく電話の直後)に必要です。parseInputmallocfree(results);aggregatedArray

最後に、補足として。私はそれが実際には:-PaggregatedArray((int*)NULL, (int)NULL);であるべきだと思います。aggregatedArray(results, resultsSize);

于 2009-12-04T16:33:35.783 に答える
1

次のステートメントは、18 バイト ("3 5 234 11 77 44 5") のメモリを割り当てます。

int *results = (int*) malloc(strlen(input));

しかし、あなたはそのメモリ領域に整数を入れています...したがって、すべてのスペースを使い果たしたときに長くは続かない...だから、それは間違いなく間違っています。

さらに.. free() 呼び出しを使い果たしていないので、それも問題になります..

于 2009-12-04T16:48:33.257 に答える
0

関数「aggregatedArray」では、mallocから返されたポインターを変数に割り当てていないため、後で解放できます。彼らは宇宙で失われます!

于 2009-12-04T16:33:39.043 に答える