【问题标题】:Thread changing heap memory线程改变堆内存
【发布时间】:2017-01-11 05:34:43
【问题描述】:

我正在编译这个程序。

char * p;    
void * handler(void * arg)
{
  p = "hello"; // initializing p 
  puts(p);
  puts("------");
  long tid = (long) arg;
  printf("Hello wrold! it is in thread : %ld\n", tid);
  pthread_exit(NULL); //exiting thread 
}

int main() {
  pthread_t t_id[2];
  int rc;
  long t;
  p = malloc(sizeof(100)); // allocating memory tried (p =malloc(sizeof(char)*100);)
  if (p == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }


  for (t = 0; t < 2; t++) {
    printf("Creating Thread  %ld\n", t);
    rc = pthread_create( & t_id[t], NULL, handler, (void * ) t);
    if (rc) {
      perror("pthread_create");
      exit(EXIT_FAILURE);
    }
  }
  pthread_join(t_id[0], NULL);
  pthread_join(t_id[1], NULL);
  free(p); /// segmentation fault here... 
  puts("***");
  //      pthread_exit(NULL);

}

我在这里遇到分段错误, 我使用gdb 进行了检查。 令人惊讶的是,p 的地址正在改变。为什么?

任何帮助将不胜感激!

使用主机 libthread_db 库“/lib/x86_64-linux-gnu/libthread_db.so.1”。

Temporary breakpoint 1, main () at thread_heap.c:27
27              p=malloc(sizeof(100));
(gdb) p p
*$1 = 0x0*    **/// adress of p**
(gdb) next
28              if(p==NULL)
(gdb) p p      
*$2 = 0x602010 ""*  **// why changed here????**
(gdb) next
35              for (t=0;t<2;t++)
(gdb) p p
$3 = 0x602010 ""
(gdb) next
37                      printf("Creating Thread  %ld\n",t);
(gdb)
Creating Thread  0
38                      rc=pthread_create(&t_id[t],NULL,handler,(void *)t);
(gdb)
[New Thread 0x7ffff77fe700 (LWP 21632)]
.
.
.

114     in pthread_join.c
(gdb)
main () at thread_heap.c:49
49      free(p);
(gdb) p p
*$4 = 0x4009e0 "hello"*   **/// again why changed here?**
(gdb)
$5 = 0x4009e0 "hello"
(gdb) step
__GI___libc_free (mem=0x4009e0) at malloc.c:2959
2959    malloc.c: No such file or directory.
(gdb) q

Program received signal SIGSEGV, Segmentation fault.
_int_free (av=0x7ffff7bb6720, p=0x4009d0, have_lock=0) at malloc.c:4098
4098    malloc.c: No such file or directory.   // Why this address changed?
(gdb)

【问题讨论】:

  • address of p changing - 嗯,这不是p 持有的值发生了变化吗?它改变了,因为你分配给p
  • 从多个线程对共享对象的非只读、非原子、非同步访问 -> 竞争条件、未定义行为。
  • 你需要使用strcpy()来复制字符串。
  • p = malloc(sizeof(100)); 随机代码突变很少有助于修复错误,不要那样做。

标签: c linux multithreading gdb


【解决方案1】:

问题出在

// in main
p = malloc(sizeof(100)); // allocating memory tried (p =malloc(sizeof(char)*100);)

// in handler function
p = "hello"; // initializing p 

这里p是一个全局变量,你之前在它上面使用过malloc。在处理程序函数中,您将p 分配给字符串文字的地址,从而产生一个悬空指针。当您尝试释放此修改后的 p 时,您会收到错误消息。

你应该做的是

const char *hell = "hello";
strcpy(p,hell);

另外,将 malloc 修复为您之前的内容。当前代码仅分配 4 个字节。 (sizeof (100)sizeof(int) 相同)

【讨论】:

  • 谢谢你...瑞诗凯诗...!!我无法理解......根据线程主进程和所有线程进程共享相同的堆内存......在切换到主进程堆栈到线程堆栈时,为什么指针地址正在改变?能否请您详细说明一下……提前谢谢……!!
  • @Jaydeep 您正在将函数 handler 传递给 pthread_create 处理函数正在更改指针。
  • 感谢瑞诗凯诗...但是,为什么处理程序仍在更改指针,但指针全局未初始化,然后它位于内存的 BSS 部分,根据线程概念,除堆栈外,所有内容都是共享的...那么它又是如何改变的呢??
  • @Jaydeep - 确实,全局变量是共享的。指针首先在主函数中修改,然后在处理函数中修改。当它回到主函数时,它得到了新的值。
  • 我还是没有...!!指针的地址或指针我也没有像任何参数一样传递我没有定义任何本地指针,那么它是如何变化的!!!!!!!!!???
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2018-01-22
  • 1970-01-01
相关资源
最近更新 更多