2012-11-20 55 views
4

我試圖將一個結構的指針傳遞給一個函數,但是當我嘗試訪問該結構時,結構中的最後一個變量缺少1字節的內存地址導致任何使用可變段錯誤。通過結構函數作爲空指針

typedef struct 
{ 
    pthread_t tID; 
    int tType; 
}sThread; 

sThread threads[MAX_THREADS]; 

typedef struct 
{ 
    int tID; 
    int sock; 
    int arg_count; 
    char *from_p, **arg_p; 
}command_struct; 

pthread_t Thread_Start(void *function, void *param) 
{ 
    pthread_t tHandle; 

    pthread_create(&tHandle, NULL, function, (void*)param); 

    return tHandle; 
} 

void cmd_test(int sock, char *from_p, char **arg_p, int arg_count) 
{ 
    if(thread_check(1)) 
    { 
    send_line(sock, "%s :test thread already running", from_p); 
    return; 
    } 

    command_struct test; 

    test.tID = thread_add(1); 
    test.arg_count = arg_count; 
    test.arg_p = arg_p; 

    threads[test.tID].tID = Thread_Start(test_cmd, &test); 
} 

void *test_cmd(void *param) 
{ 
    command_struct test = *((command_struct *)param); 

    int i = 0; 

    for(i = 1; i < test.arg_count; i++) 
    { 
    printf("%s", test.arg_p[i]); 
    } 

    thread_clear(test.tID); 
    return NULL; 
} 

正在發生的事情是內部cmd_test(功能產卵的線程)結構被正確初始化,所有的變量是正確的。

$1 = {tID = 0, sock = 5, arg_count = 5, from_p = 0xbffff254 "test", arg_p = 0xbfffec48} 

但從withing test_cmd這是一個正在運行的內螺紋的結構法缺少1個字節關閉導致arg_p地址:

$1 = {tID = 0, sock = 5, arg_count = 5, from_p = 0xbffff254 "test", arg_p = 0xffec48} 

如果我一個無用的變量添加到我的command_struct arg_p的地址結束然後變得正確,並且command_struct中的最後一個變量缺少內存地址的1個字節。

+1

有時候,你所使用的名字'argp',有時'arg'。這只是一個錯誤,試圖總結這個問題,或者它實際上是調試器中的'argp'和代碼中的'arg'?我擔心你正在調試與你想象的不同的東西,或者你包含錯誤的頭文件。解決這個問題的一種方法是,在StackOverflow上發佈問題也很有幫助,可以嘗試將程序修剪爲一個演示問題的最小示例。這樣做可能會幫助您找到它;如果沒有,你可以在這裏發佈完整的程序,這使得它更容易找到問題。 –

+0

這只是一個總結。對於那個很抱歉。讓我嘗試將示例修剪爲半實數代碼 –

+0

您爲什麼要使用void指針而不是command_struct指針的任何原因? –

回答

3

您正在向您的線程傳遞一個指向局部變量的指針 - 在線程訪問它時,內存已被重用用於其他事情。

試試這個:

void cmd_test(int sock, char *from_p, char **arg_p, int arg_count) 
{ 
    if(thread_check(1)) 
    { 
     send_line(sock, "%s :test thread already running", from_p); 
     return; 
    } 

    // === begin modified code in cmd_test(): 
    command_struct* test = malloc(sizeof(command_struct)); 

    test->tID = thread_add(1); 
    test->arg_count = arg_count; 
    test->arg_p = arg_p; 

    threads[test.tID].tID = Thread_Start(test_cmd, test); 
    // === end modified code 
} 

void *test_cmd(void *param) 
{ 
    command_struct test = *((command_struct *)param); 
    free(param); // <-- new line of code 

    // remainder is the same... 
    // ... 
} 
+0

感謝這個固定的問題,但帶來了另一個問題。我可以通過結構傳遞整數,但是當我嘗試傳遞一個指針或一個指針指針時,結果在線程中總是空白。 (在線程啓動之前的gdb中,它看起來像'$ 1 = {tID = 0,str = 0xbffff096「1.2」,throt = 90,p = 10,ti = 10}'但是我開始看起來像'$ 2 = {tID = 0,str = 0xbffff096「」,throt = 90,p = 10,ti = 10}'使用修改後的代碼(它修復了原來的內存問題) –

+0

沒關係我設法解決它通過將str定義爲'char str [18];'而不是'char * str',然後使用sprintf將arg_p變量放在它裏面,這只是一個問題,因爲我沒有爲'char * str;'? –