2013-02-14 2 views
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 (& людей [п]) отлично работает без Valgrind жалуется, где п находится в пределах стекакак сделать точку структуры к себе без Valgrind жалуясь

p_person (люди [N]. предок) делает valgrind жалуется на недопустимое чтение размера x в зависимости от того, что он читает в структуре. Например, char sex будет x = 1 Исключение составляет здесь n - это конец стека (в данном случае 4) valgrind будет не жалуйтесь, для всех случаев n результат будет напечатан штрафом.

это пример того, что Valgrind будет говорить, если я p_person (людей [п] .ancestor) где п меньше, чем в конце стека

Invalid считывания размера 8 Название: Али Zaheeruddin Недопустимый считывания размер 1 Пол: мужской Недопустимый считывания размер 4 Возраст: 24

+0

Использование вычитаний на (массив-) указывает на склонность к ошибкам, старайтесь избегать его. – alk

+0

что я должен использовать вместо этого? – lost

+0

OT: Если возможно, используйте модифицированный или другой алгоритм. Если вы меняете 'int n = this-> n + 1;' на 'int n = this-> n;', вы можете избежать, например, всех случаев появления n-1. Речь идет не о решении вашей конкретной проблемы, а о том, как правильно использовать более стабильный/безопасный код по концепции/подходу. – alk

ответ

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

Когда у вас есть 0 или 1 существующие элементы в массиве п-2 идет ниже начала массива, в результате чего неверное чтение меня mory по этому адресу (8 байтов).

+0

, это нормально, когда она переходит к 1 существующему элементу, это Человек, заполненный значениями тарабарщины, а его предком является NULL, второй элемент - настоящий человек, указывающий на либера. Дизайн плохой, я собираюсь исправить его, однако вы не ответили на вопрос о том, почему valgrind жалуется, когда есть два или более элемента. – lost

+0

Valgrind, похоже, жалуется, когда обрабатывается «Ali Zaherrunddin». Он является вторым именем, которое нужно добавить, поэтому в это время есть только 1 элемент. Вызов /*p_person(this[n-1].ancestor); // работает * /, где valgrind обнаруживает недопустимое чтение. – PQuinn

+0

ОК я исправил его, используя forloop, который переназначает всех предыдущих предков в push и pop-функциях, я думаю, что функция realloc возила что-то вверх – lost