在C struct中为char *属性分配内存

时间:2015-10-05 01:08:57

标签: c struct segmentation-fault malloc

假设我们在C文件中有以下结构定义:

typedef struct {
    char *name;
    int id;
    int last_cpu;
} thread_t;

(这是为了模拟我写的是为我的OS类使用不同的调度算法)。每次我创建一个新的thread_t结构时,如何处理其中一个变量是char*的事实?例如,我的代码中有以下方法:

thread_t **get_starting_thread_list() {
    thread_t **threads = (thread_t **) malloc(MAX_NUM_THREADS * sizeof(thread *));
    int next_id = 0;

    for (int th_num = 0; th_num < MAX_NUM_THREADS; th_num++) {
        thread_t *new_thread = (thread_t *) malloc(sizeof(thread_t));
        new_thread->name = "New thread";
        new_thread->id = ++next_id;
        new_thread->last_cpu = 0;
        threads[th_num] = new_thread;
    }

    return threads;
}

如果name的{​​{1}}字段永远是&#34;太大&#34;我可能会遇到分段错误吗?也就是说,我应该在分配之前为线程名称分配额外的内存吗?我试过这个并且看起来表现得很好,但是我担心它可能会在以后破坏。

4 个答案:

答案 0 :(得分:1)

  

如果new_thread的名称字段过长&#34;那么我是否可能会遇到分段错误?

不,你不能在那里得到一个段错误,无论strin可能有多长,因为字符串文字的内存是静态分配的,永远不会被复制。

  

也就是说,我应该在分配之前为线程名称分配额外的内存吗?

除非您打算让名称更改,否则不会。如果你想保持名称指向字符串文字,你的代码就完全没问题了。如果要对名称使用非文字数据,可以执行以下操作:

char buf[32];
sprintf(buf, "New thread %d", next_id);
new_thread->name = malloc(strlen(buf+1));
strcpy(new_thread->name, buf);

现在您需要在取消分配free(threads[i]->name)

之前致电threads
  

我已经尝试过这个并且它似乎表现得很好,但我担心它可能会在以后破坏。

你的代码很好。您始终可以使用内存分析器(例如valgrind)来检查无效访问。

答案 1 :(得分:0)

在您的代码段中,您将name指向文字字符串。如果你不打算改变它,那将永远正常。如果你想做ptr->name[0] = 'X';之类的事情你现在正试图修改固定字符串,我认为这是一种未定义的行为(观看语言律师的评论以确认或拒绝; - )。

答案 2 :(得分:0)

在你的代码中,文字字符串&#34;新线程&#34;静态分配,而不是动态分配。 (这意味着一旦应用程序启动就会存在此文本,而不是使用malloc()等函数从堆中动态分配。)因此,这将永远不会太大或导致段错误。该字符串位于静态内存中,现在您的thread_t结构将指向该内存。

但是,在这种情况下,每个结构的值都是相同的。所以我怀疑这是你的代码真正的样子。

答案 3 :(得分:0)

结构定义char *name;,无论指向什么字符串,指针的大小都不会改变。

所以这个问题的答案是:如果new_thread的名称字段“太大”,我可能会遇到分段错误吗?是NO,字符串的大小没有区别。< / p>

但是,如果定义文字字符串,则无法更改该字符串。尝试更改文字字符串的内容将导致seg错误事件,。