c - 神秘变化的结构成员(涉及指针):

标签 c pointers random memory-leaks structure

好的,所以我首先要说我对编程很陌生,不要介意这个论坛,所以如果有任何更多/更少的信息我应该提供,请告诉我。我希望我不是在问一个愚蠢的问题:P

无论如何,我正在尝试编写我的第一个完全自己工作的程序(好吧,除了用作乘法程序的简单二维数组程序)。在其中,我基本上是在尝试制作一个简单的博弈论模型。你有 2 个人可以做出选择,这是预先确定的,我将其表示为“int trait”,即 0 或 1。但是我将其扩大到最初有 100 人,并一次选择 2 个人进行随机测试,并且根据他们的特征,他们被分配不同的分数来确定他们必须进行进一步测试的“后代”数量,但这并不完全重要,因为我的问题在那之前。

我通过制作一个结构来设置我的测试对象:

struct Person { //used for testing and reproduction initialization
    int trait; // 0 for normal - 1 for phycopath
    int score; // reproductive score
    } ;
struct Person *id;

然后像这样分配内存: id = (struct Person *) malloc(n * sizeof(struct Person));

并初始化结构做:

for(i = 0; i < nn; i++) {
    id[i * sizeof(struct Person)].trait = 0;
    id[i * sizeof(struct Person)].score = 0;
}

for(i = nn; i < n; i++) {
    id[i * sizeof(struct Person)].trait = 1;
    id[i * sizeof(struct Person)].score = 0; }

在你说我做错了所有事情之前(我并不是说我没有做错),只是一些值得思考的东西,我检查它是否在之后立即正确初始化使用:

for(i = 0; i < n; i++) {
        printf("id[%d].trait = %d\t", i, id[i * sizeof(struct Person)].trait);
        printf("id[%d].score = %d\n", i, id[i * sizeof(struct Person)].score);
    } 

现在我的问题是,在我的代码中的某处(我已经做了一些测试来向我指出问题出在哪里),当我在 26 岁之间(包括 26 岁)时,测试对象的特征一直在改变和 37(每次都是)。这向我表明,我的变量 id[] 在代码中的某个地方被玩弄了,但在它的初始化和测试之间我根本不记得它。我的测试表明问题在于:

for(i = 0; i < nn; i++) {
        if(p > 0) {
        srand( time(NULL) );
        randn = rand() % p; //MAKE SURE THIS IS OK
        storea = randn;
        storeaa = randf[randn];
        testa = storeaa * sizeof(struct Person);

testa(以及程序后面的 testb)用于以与上述测试打印语句完全相同的方式记忆测试对象。<​​/p>

程序编译并运行(只是不是我想要的方式),大约每十次我尝试运行它我都会收到一个错误:

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.

这表明随机数生成器可能是错误的?还是内存泄漏 - 在哪里?老实说,我现在真的一无所知。

对于冗长但希望不会太困惑的解释,我深表歉意。我已经在这个问题上工作了整整 2 天,并花了很多时间在线研究以避免用我的问题困扰人们。任何关于出了什么问题的想法将不胜感激。为了完成这个问题,我将在下面发布我非常草率的全部代码:

#include <stdio.h>
#include <stdlib.h> 
#include <assert.h>
#include <time.h>

struct Person { //used for testing and reproduction initialization
    int trait; // 0 for normal - 1 for phycopath
    int score; // reproductive score
    } ;
struct Person *id;
int n; // number of individuals


struct Person *temp;

//remember to type functions before main!!!
int main () {
    //beginning of initialization
    int n = 100; // number of members MUST BE EVEN!!!!!!
    int nn = (n / 2);
    printf("n = %d\nnn = %d\n", n, nn); 
    if(n == 100) { printf("n set to %d \n", n); }
    id = (struct Person *) malloc(n * sizeof(struct Person));//allocate memory for id
    temp = (struct Person *) malloc(n * sizeof(struct Person));
    assert(id != NULL);
    assert(temp != NULL);   
    int i = 0;
    int testa;
    int testb; //two subjects to be used for test
    //initialize rand-function array
    int p = n; //used for decrementing array and random size
    int *randf;
    int *randt;
    int randn;
    int t;
    int r;
    int kids;
    int offs;
    int tests = 0;
    int testkids = 0;
    int storea;
    int storeaa;
    int storeb;
    int storebb;
    int size = sizeof(struct Person);
    randf = malloc( n * sizeof(int));
    randt = malloc( p * sizeof(int));
    randf = realloc(randf, n * sizeof(int)); //allocation to randf
    assert(randf != NULL);
    assert(randt != NULL);

    for(i = 0; i < nn; i++) {
        printf("initialization of non-traits begun\n");
        id[i * sizeof(struct Person)].trait = 0;
        id[i * sizeof(struct Person)].score = 0;
        printf("Person %d set\n", i);
    }

    for(i = nn; i < n; i++) {
        printf("initialization of with-traits begun\n");
        id[i * sizeof(struct Person)].trait = 1;
        id[i * sizeof(struct Person)].score = 0;
        printf("Person %d set\n", i);
    } //initialization complete
    for(i = 0; i < n; i++) {
        printf("id[%d].trait = %d\t", i, id[i * sizeof(struct Person)].trait);
        printf("id[%d].score = %d\n", i, id[i * sizeof(struct Person)].score);
    }
    //beginning of test
    i = 0;


    for(i = 0; i < n; i++) {
        randf[i] = i;
    }
    //selection and usage of test subjects
    i = 0;
    t = 0;
    r = 0;
    for(i = 0; i < nn; i++) {
        if(p > 0) {
        srand( time(NULL) );
        randn = rand() % p; //MAKE SURE THIS IS OK
        storea = randn;
        storeaa = randf[randn];
        testa = storeaa * size;
        //printf("%d\n", id[testa].trait);
        p = p - 1;
        randt = realloc(randt, p * sizeof(int));
        assert(randt != NULL);
        for(t = 0, r = 0; t < p; t++) { //copy randf over to randt exluding t = randn
            if(t != randn) {
                randt[r] = randf[t];
                r++;
            }
            else {}
        }
        randf = realloc(randf, p * sizeof(int));
        assert(randf != NULL);  
//              randf = randt;//copy randt back over to randf               
                for (t=0; t<p; t++) {
                   randf[t] = randt[t]; }
        srand( time(NULL) );
        randn = rand() % p; //MAKE SURE THIS IS RIGHT
        storeb = randn;
        storebb = randf[randn];
        testb = storebb * size;
        //printf("%d\n", id[testb].trait);
        p = p - 1;
        if( p > 0 ) { 
        randt = realloc(randt, p * sizeof(int));
        assert(randt != NULL);
            for(t = 0, r = 0; t < p; t++) { //same as before
                if(t != randn) {
                    randt[r] = randf[t];
                    r++;
                }
                else{}  
            }
            randf = realloc(randf, p * sizeof(int));
            assert(randf != NULL);
            for (t=0; t<p; t++) {
                       randf[t] = randt[t]; }
        }
        }       
        tests++;
    //TESTING TIME!!!
        if(id[testa].trait == 0 && id[testb].trait == 0) {
            id[testa].score = id[testa].score + 2;
            id[testb].score = id[testb].score + 2;
            //printf("Test Successful %d\n", tests);
        } else if(id[testa].trait == 0 && id[testb].trait == 1) {
            id[testa].score = id[testa].score + 1;
            id[testb].score = id[testb].score + 3;
            //printf("Test Successful %d\n", tests);
        } else if(id[testa].trait == 1 && id[testb].trait == 0) {
            id[testa].score = id[testa].score + 3;
            id[testb].score = id[testb].score + 1;
            //printf("Test Successful %d\n", tests);
        } else if(id[testa].trait == 1 && id[testb].trait == 1) {
            //printf("Test Successful %d\n", tests);
            // NO CHANGE
        }else {
            printf("ERROR: Test %d\n", tests);
            printf("id[testa].trait = %d\t%d,%d\n", id[testa].trait, storea, storeaa);
            printf("id[testb].trait = %d\t%d,%d\n", id[testb].trait, storeb, storebb);
        }

    } //END OF TESTING
//Commence Reproduction
    for(i = 0, kids = 0; i < n; i++) {
        kids = kids + id[i * sizeof(struct Person)].score;
        testkids ++;
        //printf("%d kids calculated\n %d parents completed\n", kids, testkids);
    }
    temp = realloc(temp, kids * sizeof(struct Person));//REMEMBER TO FREE
    assert(temp != NULL);   
    r = 0;  
    for(i = 0; i < n; i++) {
        for(offs = id[i * sizeof(struct Person)].score; offs > 0; offs--) {
            temp[r * sizeof(struct Person)].trait = id[i * sizeof(struct Person)].trait;
            temp[r * sizeof(struct Person)].score = 0;
            r++;
        }
    }
    n = kids;
    id = realloc(id, kids * sizeof(struct Person));
    assert(id != NULL);
    for(i = 0; i < n; i++) {
    id[i * sizeof(struct Person)].trait = temp[i * sizeof(struct Person)].trait;
    id[i * sizeof(struct Person)].score = temp[i * sizeof(struct Person)].score;
    }
    printf("Done!");
    free(randf);
    free(randt);
    free(temp);
    free(id);   
    return 0;
}

最佳答案

您对

的使用

id[i * sizeof(struct Person)]

没有意义。

应该是

id[i]

关于c - 神秘变化的结构成员(涉及指针):,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15242510/

相关文章:

在 C 中创建外部字符数组

C代码读取包含两列(数字)的文件并用数组打印

困惑 : Dynamic Allocation of 2D array, C

C++ 随机代理移动是相同的

C - 读取文件并打印到文件后获取无效字符,可能是缓冲区溢出

c - 为什么这些字符常量具有负值?

c - 内联汇编的弱链接

c++ - 如何定义指向 constexpr 变量的指针?

php - 随机字符串生成器 PHP

php - php中的测试数据