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]) 工作正常,没有 valgrind 抱怨 n 在堆栈范围内的位置

p_person(people[n].ancestor) 使 valgrind 抱怨大小为 x 的无效读取,具体取决于它在结构中读取的内容 Person 例如 char sex 将为 x=1 例外情况是当 n 是堆栈的末尾时(4在这种情况下)valgrind 不会抱怨,对于所有 n 的情况,结果都会被打印出来。

这是一个例子,如果我做 p_person(people[n].ancestor) 其中 n 小于堆栈的末尾,valgrind 会说什么

大小为 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 回答