假设我们在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;我可能会遇到分段错误吗?也就是说,我应该在分配之前为线程名称分配额外的内存吗?我试过这个并且看起来表现得很好,但是我担心它可能会在以后破坏。
答案 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错误事件,。