LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1663|回复: 15

删除链表函数,在centos5.5下执行正常,在gentoo下报错

[复制链接]
发表于 2010-7-26 01:34:18 | 显示全部楼层 |阅读模式
函数如下:
void dele_list(struct write_to_mysql *dele_list_begin)
  {
    struct write_to_mysql *dele_list_temp;

    dele_list_temp = dele_list_begin->next;
    dele_list_begin->pre = NULL;

    while ( dele_list_temp->pre != NULL )
      {
        free(dele_list_temp);  
        dele_list_temp = dele_list_temp->next;
      }
    free(dele_list_begin);
  }

在centos5.5下执行正常,但在gentoo下报错
错误信息如下:
*** glibc detected *** ./import: double free or corruption (!prev): 0x085027c0 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6b861)[0xb743d861]
/lib/libc.so.6(+0x6d0c8)[0xb743f0c8]
/lib/libc.so.6(cfree+0x6d)[0xb74421ad]
./import[0x8048f59]
/lib/libc.so.6(__libc_start_main+0xe6)[0xb73e8bb6]
./import[0x8048ab1]
======= Memory map: ========
08048000-0804b000 r-xp 00000000 08:01 2297491    /root/source/import
0804b000-0804c000 r--p 00003000 08:01 2297491    /root/source/import
0804c000-0804d000 rw-p 00004000 08:01 2297491    /root/source/import
084fe000-0851f000 rw-p 00000000 00:00 0          [heap]
b7200000-b7221000 rw-p 00000000 00:00 0
b7221000-b7300000 ---p 00000000 00:00 0
b7375000-b7391000 r-xp 00000000 08:01 2927173    /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7391000-b7392000 r--p 0001b000 08:01 2927173    /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7392000-b7393000 rw-p 0001c000 08:01 2927173    /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7393000-b739d000 r-xp 00000000 08:01 1744303    /lib/libnss_files-2.11.2.so
b739d000-b739e000 r--p 00009000 08:01 1744303    /lib/libnss_files-2.11.2.so
b739e000-b739f000 rw-p 0000a000 08:01 1744303    /lib/libnss_files-2.11.2.so
b73aa000-b73ab000 rw-p 00000000 00:00 0
b73ab000-b73c0000 r-xp 00000000 08:01 1744114    /lib/libpthread-2.11.2.so
b73c0000-b73c1000 r--p 00014000 08:01 1744114    /lib/libpthread-2.11.2.so
b73c1000-b73c2000 rw-p 00015000 08:01 1744114    /lib/libpthread-2.11.2.so
b73c2000-b73c4000 rw-p 00000000 00:00 0
b73c4000-b73c6000 r-xp 00000000 08:01 1744089    /lib/libdl-2.11.2.so
b73c6000-b73c7000 r--p 00001000 08:01 1744089    /lib/libdl-2.11.2.so
b73c7000-b73c8000 rw-p 00002000 08:01 1744089    /lib/libdl-2.11.2.so
b73c8000-b73c9000 rw-p 00000000 00:00 0
b73c9000-b73d0000 r-xp 00000000 08:01 1744269    /lib/librt-2.11.2.so
b73d0000-b73d1000 r--p 00006000 08:01 1744269    /lib/librt-2.11.2.so
b73d1000-b73d2000 rw-p 00007000 08:01 1744269    /lib/librt-2.11.2.so
b73d2000-b7512000 r-xp 00000000 08:01 1744323    /lib/libc-2.11.2.so
b7512000-b7514000 r--p 0013f000 08:01 1744323    /lib/libc-2.11.2.so
b7514000-b7515000 rw-p 00141000 08:01 1744323    /lib/libc-2.11.2.so
b7515000-b7518000 rw-p 00000000 00:00 0
b7518000-b763d000 r-xp 00000000 08:01 1775379    /usr/lib/libcrypto.so.0.9.8
b763d000-b763e000 ---p 00125000 08:01 1775379    /usr/lib/libcrypto.so.0.9.8
b763e000-b7646000 r--p 00125000 08:01 1775379    /usr/lib/libcrypto.so.0.9.8
b7646000-b7655000 rw-p 0012d000 08:01 1775379    /usr/lib/libcrypto.so.0.9.8
b7655000-b7658000 rw-p 00000000 00:00 0
b7658000-b769a000 r-xp 00000000 08:01 1775382    /usr/lib/libssl.so.0.9.8
b769a000-b769b000 r--p 00042000 08:01 1775382    /usr/lib/libssl.so.0.9.8
b769b000-b769e000 rw-p 00043000 08:01 1775382    /usr/lib/libssl.so.0.9.8
b769e000-b76c2000 r-xp 00000000 08:01 1744287    /lib/libm-2.11.2.so
b76c2000-b76c3000 r--p 00023000 08:01 1744287    /lib/libm-2.11.2.so
b76c3000-b76c4000 rw-p 00024000 08:01 1744287    /lib/libm-2.11.2.so
b76c4000-b76c5000 rw-p 00000000 00:00 0
b76c5000-b76d8000 r-xp 00000000 08:01 1744158    /lib/libnsl-2.11.2.so
b76d8000-b76d9000 r--p 00012000 08:01 1744158    /lib/libnsl-2.11.2.so
b76d9000-b76da000 rw-p 00013000 08:01 1744158    /lib/libnsl-2.11.2.so
b76da000-b76dc000 rw-p 00000000 00:00 0
b76dc000-b76e5000 r-xp 00000000 08:01 1744294    /lib/libcrypt-2.11.2.so
b76e5000-b76e6000 r--p 00008000 08:01 1744294    /lib/libcrypt-2.11.2.so
b76e6000-b76e7000 rw-p 00009000 08:01 1744294    /lib/libcrypt-2.11.2.so
b76e7000-b770e000 rw-p 00000000 00:00 0
b770e000-b771f000 r-xp 00000000 08:01 2395597    /lib/libz.so.1.2.3
b771f000-b7720000 r--p 00010000 08:01 2395597    /lib/libz.so.1.2.3
b7720000-b7721000 rw-p 00011000 08:01 2395597    /lib/libz.so.1.2.3
b7721000-b7839000 r-xp 00000000 08:01 1792904    /usr/lib/mysql/libmysqlclient.so.15.0.0
b7839000-b783b000 r--p 00117000 08:01 1792904    /usr/lib/mysql/libmysqlclient.so.15.0.0
b783b000-b787c000 rw-p 00119000 08:01 1792904    /usr/lib/mysql/libmysqlclient.so.15.0.0
b787c000-b787d000 rw-p 00000000 00:00 0
b7887000-b7889000 rw-p 00000000 00:00 0
b7889000-b788a000 r-xp 00000000 00:00 0          [vdso]
b788a000-b78a6000 r-xp 00000000 08:01 1744278    /lib/ld-2.11.2.so
b78a6000-b78a7000 r--p 0001b000 08:01 1744278    /lib/ld-2.11.2.so
b78a7000-b78a8000 rw-p 0001c000 08:01 1744278    /lib/ld-2.11.2.so
bfc4c000-bfc6d000 rw-p 00000000 00:00 0          [stack]
Aborted

后修改如下:
void dele_list(struct write_to_mysql *dele_list_begin)
  {                  
    struct write_to_mysql *dele_list_temp;

    dele_list_temp = dele_list_begin;
    dele_list_temp->pre = NULL;
    dele_list_temp = dele_list_temp->next;

    while ( dele_list_temp->pre != NULL )
      {
        free(dele_list_temp);
        dele_list_temp = dele_list_temp->next;
      }
    free(dele_list_begin);
  }

在验证程序中通过
#include <stdio.h>
#include <stdlib.h>

struct write_to_mysql
  {
    struct write_to_mysql *pre;
    int serial;
    int date;
    int time;
    struct write_to_mysql *next;
  };

struct write_to_mysql *init_list(struct write_to_mysql *init_list_begin)
  {
    struct write_to_mysql *init_list_cur, *init_list_temp;
    int init_list_count;

    if ( ( init_list_begin = (struct write_to_mysql *)malloc(sizeof(struct write_to_mysql)) ) == NULL )
      {
        printf("no space\n");
        exit(1);
      }

    init_list_cur = init_list_begin;

    for (init_list_count=0; init_list_count<250; init_list_count++)
      {
        if ( ( init_list_temp = (struct write_to_mysql *)malloc(sizeof(struct write_to_mysql)) ) == NULL )
          {
            printf("no space\n");
            exit(1);
          }
        init_list_cur->next = init_list_temp;
        init_list_temp->pre = init_list_cur;
        init_list_cur = init_list_cur->next;
      }

    init_list_cur->next = init_list_begin;
    init_list_begin->pre = init_list_cur;

    return(init_list_begin);
  }

void dele_list(struct write_to_mysql *dele_list_begin)
  {                  
    struct write_to_mysql *dele_list_temp;

    dele_list_temp = dele_list_begin;
    dele_list_temp->pre = NULL;
    dele_list_temp = dele_list_temp->next;

    while ( dele_list_temp->pre != NULL )
      {
        free(dele_list_temp);
        dele_list_temp = dele_list_temp->next;
      }
    free(dele_list_begin);
  }

int main()
  {
    struct write_to_mysql *global_begin;

    global_begin = init_list(global_begin);

    dele_list(global_begin);
  }

但将该函数放入程序中,运行报错:
Segmentation fault

gentoo环境:
sys-devel/gcc-4.4.3-r2
sys-libs/glibc-2.11.2
kernel-2.6.34-gentoo-r1

centos5.5环境:
gcc-4.1.2-48.el5
glibc-common-2.5-49.el5_5.2
 楼主| 发表于 2010-7-26 09:16:10 | 显示全部楼层

删除链表函数,在centos5.5下执行正常,在gentoo下报错

说明:该问题原来发在Linux程序设计的,但没有人回答,所以发在这里了。请版主手下留情。

函数如下:
void dele_list(struct write_to_mysql *dele_list_begin)
{
struct write_to_mysql *dele_list_temp;

dele_list_temp = dele_list_begin->next;
dele_list_begin->pre = NULL;

while ( dele_list_temp->pre != NULL )
{
free(dele_list_temp);
dele_list_temp = dele_list_temp->next;
}
free(dele_list_begin);
}

在centos5.5下执行正常,但在gentoo下报错
错误信息如下:
*** glibc detected *** ./import: double free or corruption (!prev): 0x085027c0 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6b861)[0xb743d861]
/lib/libc.so.6(+0x6d0c8)[0xb743f0c8]
/lib/libc.so.6(cfree+0x6d)[0xb74421ad]
./import[0x8048f59]
/lib/libc.so.6(__libc_start_main+0xe6)[0xb73e8bb6]
./import[0x8048ab1]
======= Memory map: ========
08048000-0804b000 r-xp 00000000 08:01 2297491 /root/source/import
0804b000-0804c000 r--p 00003000 08:01 2297491 /root/source/import
0804c000-0804d000 rw-p 00004000 08:01 2297491 /root/source/import
084fe000-0851f000 rw-p 00000000 00:00 0 [heap]
b7200000-b7221000 rw-p 00000000 00:00 0
b7221000-b7300000 ---p 00000000 00:00 0
b7375000-b7391000 r-xp 00000000 08:01 2927173 /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7391000-b7392000 r--p 0001b000 08:01 2927173 /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7392000-b7393000 rw-p 0001c000 08:01 2927173 /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1
b7393000-b739d000 r-xp 00000000 08:01 1744303 /lib/libnss_files-2.11.2.so
b739d000-b739e000 r--p 00009000 08:01 1744303 /lib/libnss_files-2.11.2.so
b739e000-b739f000 rw-p 0000a000 08:01 1744303 /lib/libnss_files-2.11.2.so
b73aa000-b73ab000 rw-p 00000000 00:00 0
b73ab000-b73c0000 r-xp 00000000 08:01 1744114 /lib/libpthread-2.11.2.so
b73c0000-b73c1000 r--p 00014000 08:01 1744114 /lib/libpthread-2.11.2.so
b73c1000-b73c2000 rw-p 00015000 08:01 1744114 /lib/libpthread-2.11.2.so
b73c2000-b73c4000 rw-p 00000000 00:00 0
b73c4000-b73c6000 r-xp 00000000 08:01 1744089 /lib/libdl-2.11.2.so
b73c6000-b73c7000 r--p 00001000 08:01 1744089 /lib/libdl-2.11.2.so
b73c7000-b73c8000 rw-p 00002000 08:01 1744089 /lib/libdl-2.11.2.so
b73c8000-b73c9000 rw-p 00000000 00:00 0
b73c9000-b73d0000 r-xp 00000000 08:01 1744269 /lib/librt-2.11.2.so
b73d0000-b73d1000 r--p 00006000 08:01 1744269 /lib/librt-2.11.2.so
b73d1000-b73d2000 rw-p 00007000 08:01 1744269 /lib/librt-2.11.2.so
b73d2000-b7512000 r-xp 00000000 08:01 1744323 /lib/libc-2.11.2.so
b7512000-b7514000 r--p 0013f000 08:01 1744323 /lib/libc-2.11.2.so
b7514000-b7515000 rw-p 00141000 08:01 1744323 /lib/libc-2.11.2.so
b7515000-b7518000 rw-p 00000000 00:00 0
b7518000-b763d000 r-xp 00000000 08:01 1775379 /usr/lib/libcrypto.so.0.9.8
b763d000-b763e000 ---p 00125000 08:01 1775379 /usr/lib/libcrypto.so.0.9.8
b763e000-b7646000 r--p 00125000 08:01 1775379 /usr/lib/libcrypto.so.0.9.8
b7646000-b7655000 rw-p 0012d000 08:01 1775379 /usr/lib/libcrypto.so.0.9.8
b7655000-b7658000 rw-p 00000000 00:00 0
b7658000-b769a000 r-xp 00000000 08:01 1775382 /usr/lib/libssl.so.0.9.8
b769a000-b769b000 r--p 00042000 08:01 1775382 /usr/lib/libssl.so.0.9.8
b769b000-b769e000 rw-p 00043000 08:01 1775382 /usr/lib/libssl.so.0.9.8
b769e000-b76c2000 r-xp 00000000 08:01 1744287 /lib/libm-2.11.2.so
b76c2000-b76c3000 r--p 00023000 08:01 1744287 /lib/libm-2.11.2.so
b76c3000-b76c4000 rw-p 00024000 08:01 1744287 /lib/libm-2.11.2.so
b76c4000-b76c5000 rw-p 00000000 00:00 0
b76c5000-b76d8000 r-xp 00000000 08:01 1744158 /lib/libnsl-2.11.2.so
b76d8000-b76d9000 r--p 00012000 08:01 1744158 /lib/libnsl-2.11.2.so
b76d9000-b76da000 rw-p 00013000 08:01 1744158 /lib/libnsl-2.11.2.so
b76da000-b76dc000 rw-p 00000000 00:00 0
b76dc000-b76e5000 r-xp 00000000 08:01 1744294 /lib/libcrypt-2.11.2.so
b76e5000-b76e6000 r--p 00008000 08:01 1744294 /lib/libcrypt-2.11.2.so
b76e6000-b76e7000 rw-p 00009000 08:01 1744294 /lib/libcrypt-2.11.2.so
b76e7000-b770e000 rw-p 00000000 00:00 0
b770e000-b771f000 r-xp 00000000 08:01 2395597 /lib/libz.so.1.2.3
b771f000-b7720000 r--p 00010000 08:01 2395597 /lib/libz.so.1.2.3
b7720000-b7721000 rw-p 00011000 08:01 2395597 /lib/libz.so.1.2.3
b7721000-b7839000 r-xp 00000000 08:01 1792904 /usr/lib/mysql/libmysqlclient.so.15.0.0
b7839000-b783b000 r--p 00117000 08:01 1792904 /usr/lib/mysql/libmysqlclient.so.15.0.0
b783b000-b787c000 rw-p 00119000 08:01 1792904 /usr/lib/mysql/libmysqlclient.so.15.0.0
b787c000-b787d000 rw-p 00000000 00:00 0
b7887000-b7889000 rw-p 00000000 00:00 0
b7889000-b788a000 r-xp 00000000 00:00 0 [vdso]
b788a000-b78a6000 r-xp 00000000 08:01 1744278 /lib/ld-2.11.2.so
b78a6000-b78a7000 r--p 0001b000 08:01 1744278 /lib/ld-2.11.2.so
b78a7000-b78a8000 rw-p 0001c000 08:01 1744278 /lib/ld-2.11.2.so
bfc4c000-bfc6d000 rw-p 00000000 00:00 0 [stack]
Aborted

后修改如下:
void dele_list(struct write_to_mysql *dele_list_begin)
{
struct write_to_mysql *dele_list_temp;

dele_list_temp = dele_list_begin;
dele_list_temp->pre = NULL;
dele_list_temp = dele_list_temp->next;

while ( dele_list_temp->pre != NULL )
{
free(dele_list_temp);
dele_list_temp = dele_list_temp->next;
}
free(dele_list_begin);
}

在验证程序中通过
#include <stdio.h>
#include <stdlib.h>

struct write_to_mysql
{
struct write_to_mysql *pre;
int serial;
int date;
int time;
struct write_to_mysql *next;
};

struct write_to_mysql *init_list(struct write_to_mysql *init_list_begin)
{
struct write_to_mysql *init_list_cur, *init_list_temp;
int init_list_count;

if ( ( init_list_begin = (struct write_to_mysql *)malloc(sizeof(struct write_to_mysql)) ) == NULL )
{
printf("no space\n");
exit(1);
}

init_list_cur = init_list_begin;

for (init_list_count=0; init_list_count<250; init_list_count++)
{
if ( ( init_list_temp = (struct write_to_mysql *)malloc(sizeof(struct write_to_mysql)) ) == NULL )
{
printf("no space\n");
exit(1);
}
init_list_cur->next = init_list_temp;
init_list_temp->pre = init_list_cur;
init_list_cur = init_list_cur->next;
}

init_list_cur->next = init_list_begin;
init_list_begin->pre = init_list_cur;

return(init_list_begin);
}

void dele_list(struct write_to_mysql *dele_list_begin)
{
struct write_to_mysql *dele_list_temp;

dele_list_temp = dele_list_begin;
dele_list_temp->pre = NULL;
dele_list_temp = dele_list_temp->next;

while ( dele_list_temp->pre != NULL )
{
free(dele_list_temp);
dele_list_temp = dele_list_temp->next;
}
free(dele_list_begin);
}

int main()
{
struct write_to_mysql *global_begin;

global_begin = init_list(global_begin);

dele_list(global_begin);
}

但将该函数放入程序中,运行报错:
Segmentation fault

int main()
{
struct write_to_mysql *global_begin;

global_begin = init_list(global_begin);

程序主体(global_begin)

dele_list(global_begin);
}

gentoo环境:
sys-devel/gcc-4.4.3-r2
sys-libs/glibc-2.11.2
kernel-2.6.34-gentoo-r1

centos5.5环境:
gcc-4.1.2-48.el5
glibc-common-2.5-49.el5_5.2
回复 支持 反对

使用道具 举报

发表于 2010-7-26 09:22:21 | 显示全部楼层
1. free(dele_list_temp);
2. dele_list_temp = dele_list_temp->next;
第一句已经释放了dele_list_temp资源,那么dele_list_temp->next就已经不存在了,第二句必然出错。
至于有的系统没有出错,那是碰巧了。
应该先把dele_list_temp->next保存在一个变量里面。
回复 支持 反对

使用道具 举报

发表于 2010-7-26 09:34:51 | 显示全部楼层
while ( dele_list_temp->pre != NULL )
{
free(dele_list_temp);
dele_list_temp = dele_list_temp->next;
}

都free了还可以取得next的??
回复 支持 反对

使用道具 举报

发表于 2010-7-26 10:00:57 | 显示全部楼层
Post by Mie;2105224
[php]while ( dele_list_temp->pre != NULL )
{
  free(dele_list_temp);
  dele_list_temp = dele_list_temp->next;
}[/php]

都free了还可以取得next的??
一语道破天机,呵呵
回复 支持 反对

使用道具 举报

发表于 2010-7-26 10:45:22 | 显示全部楼层
centos 5.5的glibc旧了点,这样的错误也检查不出来
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-7-26 13:52:03 | 显示全部楼层
谢谢大家的回复

问题是改进函数我给粘贴错了,抱歉。

实际改进后的函数如下:
void dele_list(struct write_to_mysql *dele_list_begin)
{
struct write_to_mysql *dele_list_temp1, *dele_list_temp2;

dele_list_temp1 = dele_list_begin->next;
dele_list_temp2 = dele_list_begin->next;
dele_list_begin->pre = NULL;
dele_list_temp2 = dele_list_temp2->next;

while ( dele_list_temp1->pre != NULL )
{
free(dele_list_temp1);
dele_list_temp1 = dele_list_temp2;
dele_list_temp2 = dele_list_temp2->next;
}
free(dele_list_begin);
}

验证程序通过,但放入实际程序中报错信息为Segmentation fault。
回复 支持 反对

使用道具 举报

发表于 2010-7-26 14:27:09 | 显示全部楼层
链表不是这么删的..你这么搞不内存错误才怪..
google一下把..
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-7-26 23:52:22 | 显示全部楼层
我想也许各位是一直在code,但我已经很久不编程了。而且只能想起c的基本语法。
我也google过,也许是关键字不对吧,要么不是通过函数删除,要么是c++的。所以才来这里发帖求助的。
如果各位有知道的,请直接告诉我。

另外,还有以下问题请教各位:
1、这个函数有问题,我指的是改进后的函数,为什么在验证程序中能够正常运行(gentoo中)?
2、在用gdb调试的时候,发现送过去的指针在dele_list_begin->pre = NULL这句后,dele_list_begin->pre就不正常,但函数内初始化的指针却能指向正常?
3、如果centos的glibc的旧,那gentoo在编译的时候也没有提示任何问题,这个怎么解释?
4、这个错误的程序已经运行一段时间了(centos),我的意思是每天都要导入一批数据,每次大概十几分钟吧(300M左右的数据),计算机是一直运行的,查看内存时一切正常,这和楼上的朋友说的好象有些出入
回复 支持 反对

使用道具 举报

发表于 2010-7-27 02:32:54 | 显示全部楼层
编译和glibc没有关系(注意不包含连接,连接时也不会做这样的检查)

编译时不提示,你要怪只能怪gcc
不过据我所知gcc到目前为止没有这个功能

除了glibc的malloc可以在运行时检查之外
有专门的工具做这个,valgrind
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表