2016-08-01 3 views
0

Я относительно новичок в c и имею сложную проблему, Я отследил ее до проблемы с распределением памяти (см. Код ниже), но не понимаю, почему компилятор делает это и будет как бы знать, как это сделать правильно. Я запускаю это на gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4). Код ниже должен составлять автономный, по крайней мере, в моей системе.Проблемы с распределением памяти с массивами в structs

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include <stdbool.h> 
#include <string.h> 
#include <ctype.h> 
#include <math.h> 
#include <time.h> 


    #define MAXCOL  100 
    typedef enum { 
    DL,     
    DLIMEPS    
    } omodel_type;  

    typedef double * pcn_type; 
    struct drd_osc_type{ 
    pcn_type aaa;  
    pcn_type ggg;  
    pcn_type ooo;  
    pcn_type ddd;  
    omodel_type omodel; 
    double beps;  
    double egap;  
    int no;    
    }; 
    typedef struct drd_osc_type * pdrd_osc; 


//===================================================================== 
unsigned long int address_int(void * ccc){ 
    char *s=malloc(100); 
    sprintf(s,"%p", ccc); 
    int x; 
    sscanf(s,"%x",&x); 
    return x; 
} 

//===================================================================== 

pdrd_osc ini_drdosc(){ 
    pdrd_osc ccc; 

    if ((ccc=malloc(sizeof(pdrd_osc)))==NULL){ 
     perror("malloc 3"); 
    printf("ini_drdosc :malloc failed\n"); 
     return NULL; 
    } 
    ccc->omodel=DL; 
    ccc->no=0; 
    ccc->beps=1; 
    ccc->egap=0; 
    ccc->aaa=malloc(100*sizeof(double)); 
    ccc->ggg=malloc(100*sizeof(double)); 
    ccc->ooo=malloc(100*sizeof(double)); 
    ccc->ddd=malloc(100*sizeof(double)); 
    int i; 
    for (i=0;i<MAXCOL;i++)ccc->aaa[i]=0.0; 
    for (i=0;i<MAXCOL;i++)ccc->ggg[i]=0.0; 
    for (i=0;i<MAXCOL;i++)ccc->ooo[i]=0.0; 
    for (i=0;i<MAXCOL;i++)ccc->ddd[i]=0.0; 
    //printf("Hello\n"); 
    printf(" SIZE OF ccc    : %i\n", (int) sizeof(pdrd_osc)); 
    printf(" ADDRESS ccc    : %p\n", ccc); 
    printf(" ADDRESS (INT) ccc  : %lu\n", address_int(ccc)); 
    printf(" ADDRESS ccc.omodel  : %lu\n", address_int(&(ccc->omodel))); 
    printf(" ADDRESS ccc.no   : %lu\n",  address_int(&(ccc->no))); 
    printf(" ADDRESS ccc.beps  : %lu\n", address_int(&(ccc->beps))); 
    printf(" ADDRESS ccc.egap  : %lu\n", address_int(&(ccc->egap))); 
    printf(" ADDRESS ccc.aaa   : %lu\n", address_int(&(ccc->aaa))); 
    printf(" ADDRESS ccc.aaa[0]  : %lu\n", address_int(&(ccc->aaa[0]))); 
    printf(" ADDRESS ccc.aaa[maxcol] : %lu\n", address_int(&(ccc->aaa[MAXCOL]))); 
    printf(" ADDRESS ccc.ggg   : %lu\n", address_int(&(ccc->ggg))); 
    printf(" ADDRESS ccc.ooo   : %lu\n", address_int(&(ccc->ooo))); 
    printf(" ADDRESS ccc.ddd   : %lu\n", address_int(&(ccc->ddd))); 
    return ccc; 
} 
int main(int argc, char* argv[]) { 
pdrd_osc drdosc;drdosc=(pdrd_osc) ini_drdosc(); 
    return 0; 
} 

Когда я скомпилировать и запустить его, я получаю следующий результат:

SIZE OF ccc    : 8 
ADDRESS ccc    : 0x1086010 
ADDRESS (INT) ccc  : 17326096 
ADDRESS ccc.omodel  : 17326128 
ADDRESS ccc.no   : 17326152 
ADDRESS ccc.beps  : 17326136 
ADDRESS ccc.egap  : 17326144 
ADDRESS ccc.aaa   : 17326096 
ADDRESS ccc.aaa[0]  : 17326128 
ADDRESS ccc.aaa[maxcol] : 17326928 
ADDRESS ccc.ggg   : 17326104 
ADDRESS ccc.ooo   : 17326112 
ADDRESS ccc.ddd   : 17326120 

Таким образом, первый malloc в функции ini_drdosc запасов в памяти 8 байт, что хорошо. Однако адресное пространство, зарезервированное этим malloc для переменных omodel,no,beps и egap, заменяется следующим malloc для (фиксированного размера массива) aaa, поскольку демонстрируется отпечаток адресов aaa[0] и aaa[maxcol]. Зачем? Как заставить компилятор защитить переменные omodel,no,beps и egap во избежание segfaults и т. Д.?

Я действительно полностью застрял здесь и буду благодарен за любую помощь, которую я мог бы получить. Заранее благодарим за вашу любезную помощь!

ответ

2

Вы берете sizeof указателя типа, а не самой структуры. В зависимости от 64/32-битной системы это будет 8 и 4 байта.

ccc=malloc(sizeof(drd_osc_type))); 

Следует выделить правильный размер.

+1

Или что-то вроде 'sizeof (* pdrd_osc)'. –

+0

ОК, большое спасибо. Глупая ошибка с моей стороны. Вы становитесь настолько слепыми, когда смотрите на неверный код на тонком, особенно, конечно, в c со всеми амперсандами и звездочками и т. Д. В любом случае, Большое спасибо за вашу помощь !!!! Я очень ценю это. Следующие изменения сделали трюк 'typedef struct drd_osc_type drd_osc;' 'typedef drd_osc * pdrd_osc;' 'if ((ccc = malloc (sizeof (drd_osc))) == NULL) {etc..' –

Смежные вопросы