内存管理 内存分配

add_oil 2013-02-03 08:34:09
typedef struct a{
char *msg;}A
typedef struct b{
struct A **__ptr;
int size;

}B;
struct pkt{
u_int32_t size;
char data[0];
} __attribute__((packed));
typedef struct pkt PKT;
有这样三个结构体 type msg 里面存有数据 打算把结构体B放于PKT 的data【0】
这样的话 一般来说申请 内存应该要怎样做 比较好
1:假如msg是由tmp来的
A *a1;B *b1;
size=sizeof(PKT)+sizeof(int);
pkt=(PKT*)malloc(size);
b1=(B *)pkt->data;
b1.size=1;
然后再申请A的地址?
b1.__ptr=(A**)malloc((b1.size)*sizeof(A*));
b1.__ptr[0]=(A *)malloc(sizeof(A));
(b1.__ptr[0])->msg=(char *)malloc(sizeof(char [strlen(tmp)+1]));
strcpy((b1.__ptr[0])->msg,tmp);
这样做的话 在另外一端data【0】 取出来的数据 用好了后 要free的话 岂不是可能会出现内存泄露??而且要知道data【0】 存数据的长度 我们也不能得知吧
是否有更好的解决方法没有
另外我想到 是否可以这样:例如是可以在PKT 申请足够的空间 让 A B 指向哪里 然后 使用后 直接 free掉PKT申请的空间 就可以了??
...全文
3249 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
dreamgis 2013-02-17
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo De……
只要功夫深,铁杵磨成针
赵4老师 2013-02-05
  • 打赏
  • 举报
回复
推荐楼主研习一下Google protobuf
add_oil 2013-02-05
  • 打赏
  • 举报
回复
引用 19 楼 zhao4zhong1 的回复:
推荐楼主研习一下Google protobuf
好的 谢谢!
add_oil 2013-02-04
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
个人意见,最好不用malloc。参考下面: C/C++ code ? 12345678910111213141516171819202122232425262728293031323334353637 //使用动态分配 #include <stdio.h> #include <stdlib.h> #include <malloc.h> int i,L; char *……
必须使用动态分配啊 就我提的那个例子 我想问的是 如果 这样的话 是否 可以: size=sizeof(PKT)+sizeof(B)+sizeof(A)+strlen(tmp)+1; pkt=(PKT_BACPHDR_t*)malloc(size); b1=(B *)pkt->data; b1->size=1; b1->__ptr=(A**)(pkt->data+sizeof(int)); b1->__ptr[0]=(A *)(pkt->data+sizeof(A)); (b1->__ptr[0])->msg=(char *)(pkt->data+sizeof(B)+sizeof(A)); 然后用完后 在另外一端 直接free掉pkt 就好了? 耐心看一下 谢谢
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
个人意见,最好不用malloc。参考下面:
//使用动态分配
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int i,L;
char *p;
void main() {
    for (i=0;i<20000;i++) {
        L=rand();
        p=malloc(L);
        if (NULL==p) {
            printf("malloc error!\n");
            continue;
        }
        memset(p,0,L);
        free(p);
    }
}
//不使用动态分配
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAXLEN 30000
int i,L;
char buf[MAXLEN];
char *p;
void main() {
    p=&buf[0];
    for (i=0;i<20000;i++) {
        L=rand();
        if (L>MAXLEN) {
            printf("L>MAXLEN==%d, ignore spilth.\n",MAXLEN);
            L=MAXLEN;
        }
        memset(p,0,L);
    }
}
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
引用 6 楼 heziyan1 的回复:
引用 3 楼 zhao4zhong1 的回复:通常应遵循“谁malloc,谁free”的原则。 你给的例子 需要时间消化一下 ,我的意思是 如果要把结构体B(B包含A的数据)赋予 PKT中的data【0】 传给另外一个函数 ,那free 也只能在另外一个函数用完的时候才free啊 ,那如果直接free PKT的话 PKT不包含A中msg 部分 会造成内存泄露吧? 不……
由调用malloc的模块暴露出一个free接口函数给使用方,当使用方认为可以free的时候,调用这个free接口函数。
manpages 2013-02-04
  • 打赏
  • 举报
回复
C A Reference Manual, 5th, 5.6.8 Flexible Array Members struct Vec { int len; double vec[] }; /* before C99: struct Vec { int len; double vec[1] }; */ struct Vec p; int n; p = malloc(sizeof (struct Vec) + n * sizeof (double)); p.len = n; /* p = malloc(sizeof (struct Vec) + (n - 1) * sizeof (double)); */
manpages 2013-02-04
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo De……
操,白刺,vc你祖宗
add_oil 2013-02-04
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
通常应遵循“谁malloc,谁free”的原则。
你给的例子 需要时间消化一下 ,我的意思是 如果要把结构体B(B包含A的数据)赋予 PKT中的data【0】 传给另外一个函数 ,那free 也只能在另外一个函数用完的时候才free啊 ,那如果直接free PKT的话 PKT不包含A中msg 部分 会造成内存泄露吧? 不知道我这样表达是否清楚。。。
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
个人建议:摒弃sizeof,使用自己定义的size变量。参考下面:
//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
struct FB {
    char fn[256];
    size_t fl;
    char *b;
    struct FB *next;
    struct FB *prev;
} *fh,*fb,*ft;
char ln[256];
char fpn[256];
FILE *af;
FILE *f;
int L,n;
int main() {
    system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");
    af=fopen("c:\\allfn.txt","r");
    if (NULL==af) {
        printf("Can not open file c:\\allfn.txt!\n");
        return 1;
    }
    fh=NULL;
    fb=NULL;
    n=0;
    while (1) {
        if (NULL==fgets(ln,256,af)) break;
        L=strlen(ln);
        if ('\n'==ln[L-1]) ln[L-1]=0;
        printf("read %s\n",ln);
        strcpy(fpn,"c:\\tmp\\");
        strcat(fpn,ln);
        ft=(struct FB *)malloc(sizeof(struct FB));
        if (NULL==ft) {
            printf("Can not malloc ft!\n");
            fclose(af);
            return 2;//之前的malloc在main退出后由操作系统自动free
        }
        printf("ft[%d]==%p\n",n,ft);
        strcpy(ft->fn,fpn);
        f=fopen(fpn,"rb");
        if (NULL==f) {
            printf("Can not open file %s!\n",fpn);
            fclose(af);
            return 3;//之前的malloc在main退出后由操作系统自动free
        }
        ft->fl=_filelength(fileno(f));
        ft->b=malloc(ft->fl);
        if (NULL==ft->b) {
            printf("Can not malloc ft->b!\n");
            fclose(f);
            fclose(af);
            return 4;//之前的malloc在main退出后由操作系统自动free
        }
        printf("ft[%d]->b==%p\n",n,ft->b);
        if (ft->fl!=fread(ft->b,1,ft->fl,f)) {
            printf("fread error!\n");
            fclose(f);
            fclose(af);
            return 5;//之前的malloc在main退出后由操作系统自动free
        }
        fclose(f);
        ft->next=NULL;

        if (NULL==fh) {
            ft->prev=NULL;
            fh=ft;
        } else {
            fb->next=ft;
            ft->prev=fb;
        }
        fb=ft;
        n++;
    }
    fclose(af);
    printf("-----list-----\n");
    for (ft=fh;NULL!=ft;ft=ft->next) {
        printf("%8d %s\n",ft->fl,ft->fn);
        if (NULL!=ft) fb=ft;
    }
    printf("-----free-----\n");
    n--;
    if (NULL!=fh) {
        for (ft=fb->prev;NULL!=ft;ft=ft->prev) {
            if (NULL!=ft->next->b) {
                printf("ft[%d]->b==%p\n",n,ft->next->b);
                free(ft->next->b);
            }
            if (NULL!=ft->next) {
                printf("ft[%d]==%p\n",n,ft->next);
                free(ft->next);
            }
            n--;
        }
        if (NULL!=fh->b) {
            printf("ft[0]->b==%p\n",fh->b);
            free(fh->b);
        }
        printf("ft[0]==%p\n",fh);
        free(fh);
    }
    return 0;
}
//C:\tmp\tmp\Debug>dir /a-d c:\tmp
// 驱动器 C 中的卷是 C_HD5_1
// 卷的序列号是 1817-D526
//
// c:\tmp 的目录
//
//找不到文件
//
//C:\tmp\tmp\Debug>tmp
//找不到文件
//-----list-----
//-----free-----
//
//C:\tmp\tmp\Debug>dir /a-d c:\tmp
// 驱动器 C 中的卷是 C_HD5_1
// 卷的序列号是 1817-D526
//
// c:\tmp 的目录
//
//2011-06-30  18:04            44,840 my_c.rar
//2011-06-30  17:18             1,036 err.frm
//2011-06-30  14:32            14,243 出租.txt
//2011-06-28  12:08            23,681 MSDN98书签.txt
//             4 个文件         83,800 字节
//             0 个目录 17,041,870,848 可用字节
//
//C:\tmp\tmp\Debug>tmp
//read my_c.rar
//ft[0]==00421800
//ft[0]->b==00520068
//read err.frm
//ft[1]==00421670
//ft[1]->b==0052AFC0
//read 出租.txt
//ft[2]==00421530
//ft[2]->b==00378F28
//read MSDN98书签.txt
//ft[3]==004213F0
//ft[3]->b==0052B3F8
//-----list-----
// 44840 c:\tmp\my_c.rar
//  1036 c:\tmp\err.frm
// 14243 c:\tmp\出租.txt
// 23681 c:\tmp\MSDN98书签.txt
//-----free-----
//ft[3]->b==0052B3F8
//ft[3]==004213F0
//ft[2]->b==00378F28
//ft[2]==00421530
//ft[1]->b==0052AFC0
//ft[1]==00421670
//ft[0]->b==00520068
//ft[0]==00421800
//
//C:\tmp\tmp\Debug>
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
如果所谓另一端不是跨进程的话,参考下面:
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <process.h>
#include <io.h>
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
#define ASIZE    200
#define BSIZE    240
#define CSIZE      2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
    int  head;
    int  tail;
    int  size;
    char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
    int i,j,k;
    char binstr[80];

    Lock(&cs_HEX);
    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%03d %04x -",cn,i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            Log("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        Log("%s\n",binstr);
    }
    Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    lent=0;
    Lock(cs);
    if (fbuf->size>=len) {
        lent=len;
        if (fbuf->head+lent>BSIZE) {
            len1=BSIZE-fbuf->head;
            memcpy(buf     ,fbuf->data+fbuf->head,len1);
            len2=lent-len1;
            memcpy(buf+len1,fbuf->data           ,len2);
            fbuf->head=len2;
        } else {
            memcpy(buf     ,fbuf->data+fbuf->head,lent);
            fbuf->head+=lent;
        }
        fbuf->size-=lent;
    }
    Unlock(cs);
    return lent;
}
void thdB(void *pcn) {
    char        *recv_buf;
    int          recv_nbytes;
    int          cn;
    int          wc;
    int          pb;

    cn=(int)pcn;
    Log("%03d thdB              thread begin...\n",cn);
    while (1) {
        Sleep(10);
        recv_buf=(char *)Cbuf;
        recv_nbytes=CSIZE;
        wc=0;
        while (1) {
            pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
            if (pb) {
                Log("%03d recv %d bytes\n",cn,pb);
                HexDump(cn,recv_buf,pb);
                Sleep(1);
            } else {
                Sleep(1000);
            }
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    Lock(cs);
    lent=len;
    if (fbuf->size+lent>BSIZE) {
        lent=BSIZE-fbuf->size;
    }
    if (fbuf->tail+lent>BSIZE) {
        len1=BSIZE-fbuf->tail;
        memcpy(fbuf->data+fbuf->tail,buf     ,len1);
        len2=lent-len1;
        memcpy(fbuf->data           ,buf+len1,len2);
        fbuf->tail=len2;
    } else {
        memcpy(fbuf->data+fbuf->tail,buf     ,lent);
        fbuf->tail+=lent;
    }
    fbuf->size+=lent;
    Unlock(cs);
    return lent;
}
void thdA(void *pcn) {
    char        *send_buf;
    int          send_nbytes;
    int          cn;
    int          wc;
    int           a;
    int          pa;

    cn=(int)pcn;
    Log("%03d thdA              thread begin...\n",cn);
    a=0;
    while (1) {
        Sleep(100);
        memset(Abuf,a,ASIZE);
        a=(a+1)%256;
        if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
        send_buf=(char *)Abuf;
        send_nbytes=ASIZE;
        Log("%03d sending %d bytes\n",cn,send_nbytes);
        HexDump(cn,send_buf,send_nbytes);
        wc=0;
        while (1) {
            pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
            Log("%03d sent %d bytes\n",cn,pa);
            HexDump(cn,send_buf,pa);
            send_buf+=pa;
            send_nbytes-=pa;
            if (send_nbytes<=0) break;//
            Sleep(1000);
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
}
int main() {
    InitializeCriticalSection(&cs_log );
    Log("Start===========================================================\n");
    InitializeCriticalSection(&cs_HEX );
    InitializeCriticalSection(&cs_BBB );

    BBB.head=0;
    BBB.tail=0;
    BBB.size=0;

    _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
    _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);

    if (!access("No_Loop",0)) {
        remove("No_Loop");
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    while (1) {
        Sleep(1000);
        if (No_Loop) break;//
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    Sleep(3000);
    DeleteCriticalSection(&cs_BBB );
    DeleteCriticalSection(&cs_HEX );
    Log("End=============================================================\n");
    DeleteCriticalSection(&cs_log );
    return 0;
}
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
通常应遵循“谁malloc,谁free”的原则。
add_oil 2013-02-04
  • 打赏
  • 举报
回复
再顶一次 是否可以 size=sizeof(PKT)+sizeof(B)+sizeof(A)+strlen(tmp)+1; pkt=(PKT_BACPHDR_t*)malloc(size); b1=(B *)pkt->data; b1->size=1; b1->__ptr=(A**)(pkt->data+sizeof(int)); b1->__ptr[0]=(A *)(pkt->data+sizeof(A)); (b1->__ptr[0])->msg=(char *)(pkt->data+sizeof(B)+sizeof(A)); 然后用完后 在另外一端 直接free掉pkt 就好了?
add_oil 2013-02-04
  • 打赏
  • 举报
回复
引用 15 楼 zhao4zhong1 的回复:
引用 13 楼 heziyan1 的回复: 引用 11 楼 zhao4zhong1 的回复:纠正上帖 test.c C/C++ code ? 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616……
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
引用 13 楼 heziyan1 的回复:
引用 11 楼 zhao4zhong1 的回复:纠正上帖 test.c C/C++ code ? 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 ……
当然可以。 几次malloc对应几次free
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认: 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物; 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、……
add_oil 2013-02-04
  • 打赏
  • 举报
回复
引用 11 楼 zhao4zhong1 的回复:
纠正上帖 test.c C/C++ code ? 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 #include <stdio.h> #include <string.……
看了例子 这样的话 要free的 我明白 只是有没有是可以 就是在PKT 申请足够的空间 然后让a b 指向哪里 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<string.h>
#define BACP_ALARM	0xb0
typedef struct ns_MsgItem
{
    char *msg;

}NS_MSGITEM_t;

typedef struct ns_MsgList
{
    struct ns_MsgItem **__ptr;
    int __size;
    
}NS_MSGLIST_t;

struct pkt_bacphdr
{
  
    u_int32_t       size;
    char            data[0];
} __attribute__((packed));
typedef  struct pkt_bacphdr    PKT_BACPHDR_t;

int main()
{


char *tmp="123456789";


//NS_MSGLIST_t      ns_list1;
NS_MSGITEM_t      **ns_item1   =     NULL;

NS_MSGLIST_t      *ns_list2=NULL;
PKT_BACPHDR_t     *pkt        =     NULL;

int size;


size=sizeof(PKT_BACPHDR_t)+sizeof(NS_MSGLIST_t)+sizeof(NS_MSGITEM_t)+sizeof(char [strlen(tmp)+1]);


pkt=(PKT_BACPHDR_t*)malloc(size);

ns_list2=(NS_MSGLIST_t *)pkt->data;


ns_list2->__size=1;

ns_list2->__ptr=(NS_MSGITEM_t**)(pkt->data+sizeof(int));
ns_list2->__ptr[0]=(NS_MSGITEM_t *)(pkt->data+sizeof(NS_MSGLIST_t));
(ns_list2->__ptr[0])->msg=(char *)(pkt->data+sizeof(NS_MSGLIST_t)+sizeof(NS_MSGITEM_t));

  printf("addr of info is %p. addr of data is %p ,%p.,%p,%p,%p,%p,%p\n", pkt, pkt->data,ns_list2,ns_list2->__ptr,ns_list2->__ptr[0],((ns_list2->__ptr[0])->msg)+10,((ns_list2->__ptr[0])->msg),pkt);

strcpy((ns_list2->__ptr[0])->msg,tmp);

 NS_MSGLIST_t      *ns_list3=NULL;
 ns_list3=(NS_MSGLIST_t *)pkt->data;
printf("%s\n",ns_list3->__ptr[0]->msg);
pkt->size=1;
free(pkt);

}
这部分代码 通过valgrind 测试没有内存泄露 你看看 这种是不是一种解决方法
add_oil 2013-02-04
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
test.cpp C/C++ code ? 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <mal……
谢谢 我看下你之前给的 例子 再琢磨下 吧 谢谢了
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
纠正上帖 test.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#pragma pack(push,1)
struct A {
    char           *msg;
};
struct B {
    struct A      **__ptr;
    int             size;
};
struct PKT {
     unsigned int   size;
     char           data[0];
};
#pragma pack(pop)
int main() {
    struct PKT *pPK;
    struct B *pb;
    int i;

    pPK=(struct PKT *)malloc(sizeof(struct PKT)+sizeof(struct B));
    if (NULL==pPK) return 1;
    pPK->size=sizeof(struct PKT)+sizeof(struct B);
    pb=(struct B *)(&(pPK->data));
    pb->__ptr=(struct A **)malloc(2*sizeof(struct A *));
    if (NULL==pb->__ptr) return 2;

    pb->size=2;

    pb->__ptr[0]=(struct A *)malloc(sizeof(struct A));
    if (NULL==pb->__ptr[0]) return 3;
    pb->__ptr[0]->msg=(char *)malloc(10*sizeof(char));
    if (NULL==pb->__ptr[0]->msg) return 4;
    strcpy(pb->__ptr[0]->msg,"123456789");

    pb->__ptr[1]=(struct A *)malloc(sizeof(struct A));
    if (NULL==pb->__ptr[1]) return 3;
    pb->__ptr[1]->msg=(char *)malloc(20*sizeof(char));
    if (NULL==pb->__ptr[1]->msg) return 4;
    strcpy(pb->__ptr[1]->msg,"1234567890123456789");

    printf("pPK==%p\n",pPK);
    printf("pPK->size==%d,pPK->data==%p\n",pPK->size,pPK->data);
    printf("pb==%p\n",pb);
    printf("pb->size==%d,pb->__ptr==%p\n",pb->size,pb->__ptr);
    printf("pb->__ptr[0]==%p pb->__ptr[0]->msg==%p \"%s\"\n",pb->__ptr[0],pb->__ptr[0]->msg,pb->__ptr[0]->msg);
    printf("pb->__ptr[1]==%p pb->__ptr[1]->msg==%p \"%s\"\n",pb->__ptr[1],pb->__ptr[1]->msg,pb->__ptr[1]->msg);

    pb=(struct B *)&pPK->data;
    for (i=pb->size-1;i>=0;i--) {
        free(pb->__ptr[i]->msg);
        free(pb->__ptr[i]);
    }
    free(pb->__ptr);
    free(pPK);
    return 0;
}
//pPK==004119A0
//pPK->size==12,pPK->data==004119A4
//pb==004119A4
//pb->size==2,pb->__ptr==00411960
//pb->__ptr[0]==00410030 pb->__ptr[0]->msg==00411920 "123456789"
//pb->__ptr[1]==004118F0 pb->__ptr[1]->msg==004118B0 "1234567890123456789"
赵4老师 2013-02-04
  • 打赏
  • 举报
回复
test.cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#pragma pack(push,1)
typedef struct a {
    char           *msg;
} A;
typedef struct b {
    struct A      **__ptr;
    int             size;
} B;
struct pkt {
     unsigned int   size;
     char           data[0];
};
typedef struct pkt PKT;
#pragma pack(pop)
int main() {
    PKT *msg;
    B *pb;
    int i;

    msg=(PKT *)malloc(sizeof(PKT)+sizeof(B));
    if (NULL==msg) return 1;
    msg->size=sizeof(PKT)+sizeof(B);
    pb=(B *)&msg->data;
    pb->__ptr=(A **)malloc(2*sizeof(A *));
    if (NULL==pb->__ptr) return 2;
    pb->size=2;
    pb->__ptr[0]=(A *)malloc(10*sizeof(char));
    if (NULL==pb->__ptr[0]) return 3;
    strcpy(pb->__ptr[0],"123456789");
    pb->__ptr[1]=(A *)malloc(20*sizeof(char));
    if (NULL==pb->__ptr[1]) return 3;
    strcpy(pb->__ptr[1],"1234567890123456789");

    printf("msg==%p\n",msg);
    printf("msg->size==%d,msg->data==%p\n",msg->size,msg->data);
    printf("pb==%p\n",pb);
    printf("pb->size==%d,pb->__ptr==%p\n",pb->size,pb->__ptr);
    printf("pb->__ptr[0]==%p \"%s\",pb->__ptr[1]==%p \"%s\"\n",pb->__ptr[0],pb->__ptr[0],pb->__ptr[1],pb->__ptr[1]);

    pb=(B *)&msg->data;
    for (i=pb->size-1;i>=0;i--) free(pb->__ptr[i]);
    free(pb->__ptr);
    free(msg);
    return 0;
}
加载更多回复(1)

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧