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

struct Person{
    char *name;
    char sex;
    int age;
    struct Person *ancestor;       
    int n;
};

void p_person(struct Person *this);

struct Person *stack_init()
{
    struct Person *this=malloc(sizeof(struct Person));
    assert(this!=NULL);

    this->name=strdup("NULL");
    this->sex='0';
    this->age=-1;
    this->ancestor=NULL;
    this->n=1;

    return this;
}

struct Person *pushPerson(struct Person *this, char *name, char sex, int age)
{
    assert(this!=NULL);
    int n=this->n+1;
    this=realloc(this,sizeof(struct Person)*n);

    this[n-1].name=strdup(name);
    this[n-1].sex=sex;
    this[n-1].age=age;
    this[n-1].ancestor=&this[n-2];

    printf("pushing new person onto stack\n");
    printf("stack increasing to %d\n",this->n);
    p_person(&this[n-1]);

    this->n=this->n+1;
    /*p_person(this[n-1].ancestor); //it works*/
    printf("----------------\n\n");

    return this;
}

struct Person *popPerson(struct Person *this)
{
    assert(this!=NULL);
    printf("Person being popped:\n");
    p_person(&this[this->n-1]);
    printf("resizing stack to %d\n", this->n-2);
    printf("----------------\n\n");
    free(this[this->n-1].name);
    int n=this->n-1;
    this=realloc(this,sizeof(struct Person)*n);

    this->n=this->n-1;

    return this;
}

void p_person(struct Person *this)
{
    printf("Name: %s\n",this->name);
    printf("Sex: %c\n",this->sex);
    printf("Age: %d\n",this->age);
}

void p_person_stack(struct Person *this)
{
    printf("printing stack...........\n");
    struct Person *current;
    int i;
    for(i=1;i<this->n;i++)
    {
        current=&this[i];
        p_person(current);
        printf("---------\n");
    }
    printf("stack printed~~~~~~~~~~\n\n");
}

void d_person_stack(struct Person *this)
{
    int i;
    for(i=0;i<this->n;i++)
        free(this[i].name);
    free(this);
}

int main(int argc, char *argv[])
{
    struct Person *people=stack_init();

    people=pushPerson(people,"Mojo jojo", 'M', 33);
    people=pushPerson(people,"Ali Zaheeruddin", 'M', 24);
    people=pushPerson(people,"Mahdi Moosa", 'M', 24);
    people=pushPerson(people,"Solid Snake", 'M', 51);  

    d_person_stack(people);

    return 0;
}

p_person(&people[n]) は、n がスタックの範囲内にある場合に valgrind が不平を言うことなく正常に動作します

p_person(people[n].ancestor) は、valgrind がサイズ x の無効な読み取りについて不平を言うようにします。これは、構造体 Person で読み取っているものに応じて異なります。この場合) valgrind は文句を言いません。n のすべてのケースで、結果は正常に出力されます。

これは、p_person(people[n].ancestor) を実行した場合に valgrind が言うことの例です。ここで、n はスタックの末尾よりも小さいです。

サイズ 8 の無効な読み取り 名前: Ali Zaheeruddin サイズ 1 の無効な読み取り 性別: M サイズ 4 の無効な読み取り 年齢: 24

4

1 に答える 1

3
this[n-1].ancestor=&this[n-2];

配列に 0 または 1 つの既存の要素がある場合、n-2 は配列の先頭より下になり、そのアドレス (8 バイト) でメモリの無効な読み取りが発生します。

于 2013-02-14T08:01:10.770 に答える