2015-10-20 19 views
0

我使用自定義函數連接少數字符串。這些函數能夠正常工作,並且我得到了正確的值,但是在少數語句之後,char指針中的值被破壞。我不明白這背後的原因。以下是更大功能的一部分。我只是提供代碼,直到其中發生腐敗本地變量的突然數據損壞

char* my_strcpy(char*dest, const char* src, int hasLen, int length) { 
    if (!hasLen) { 
     while ((*dest = *src++)) 
      ++dest; 

    } else { 
     while (length-- && (*dest = *src++)) 
      ++dest; 
    } 
    return dest; 
} 
int addSubscriptionInCache(subs_t* subs, str* pres_uri, int read_response) { 

    redisReply *reply; 

    char temp_key[1] = ""; 
    char *tk = my_strcpy(temp_key, "", 0, 0); 
    char *subs_cache_key = tk; 

    char temp_value[1] = ""; 
    char *tv = my_strcpy(temp_value, "", 0, 0); 
    char *subs_cache_value = tv; 

    tk = my_strcpy(tk, SUBSCRIPTION_SET_PREFIX, 0, 0); 
    tk = my_strcpy(tk, "-", 0, 0); 
    tk = my_strcpy(tk, subs->pres_uri.s, 0, 0); 
    tk = my_strcpy(tk, ":", 0, 0); 
    tk = my_strcpy(tk, subs->event->name.s, 0, 0); 
    *tk = '\0'; 

    // this prints correctly. 
    printf("subs_cache_key: %d %s \n", strlen(subs_cache_key), subs_cache_key); 

    int subs_cache_value_len = subs->callid.len + subs->to_tag.len + 1; // add 1 for : 

    tv = my_strcpy(tv, subs->to_tag.s, 1,subs->to_tag.len); 
    tv = my_strcpy(tv, ":", 0, 0); 
    tv = my_strcpy(tv, subs->callid.s, 1,subs->callid.len); 
    *tv= '\0'; 
    // this prints correctly. 
    printf("subs_cache_value: %d %s \n", strlen(subs_cache_value), subs_cache_value); 

    //add in pipeline 
    redisAppendCommand(redis_context, "SADD %s %s", subs_cache_key, subs_cache_value)) 
    //set expires 
    redisAppendCommand(redis_context, "EXPIRE %s %d", subs_cache_key, subs->expires); 

    // create hash for to_tag:call_id 
    int argc = 0; 
    char *arvg[22]; 
    size_t argvlen[22]; 
    // this prints fine. 
    printf("Before corruption: %s", subs_cache_value); 
    arvg[argc] = "HMSET"; 
    // below prints corrupted values 
    printf("After corruption: %s", subs_cache_value); 
    printf("After corruption: %s", subs_cache_key); 
    argvlen[argc] = 5; 
    argc++; 

    arvg[argc] = subs_cache_value; 
    argvlen[argc] = subs_cache_value_len; 
    argc++; 

    ....... 
    //rest of the code 
    } 

我使用自定義功能,使不能一次又一次地遍歷整個字符串。

請幫我理解我是否因爲發生了腐敗而做了一些事情。

感謝

+0

你嘗試使用內存調試器來調試你的程序?如[valgrind](http://valgrind.org/) –

+2

現在,閱讀代碼後。你不會把字符串分配到任何地方?您正在使用單個字符'temp_value [1]'來保存字符串。您必須分配它們或使用足夠大的緩衝區。 –

+0

我無法使用valgrind。實際上,這是一個服務器代碼,只有當它接收到一個請求時纔會執行,但是當我在valgrind中使用它時,valgrind不會等待請求,只是通過在init函數上執行而退出。 – user3275095

回答

1

你有

char temp_key[1] = ""; 
char *tk = my_strcpy(temp_key, "", 0, 0); 

,並繼續在後續調用使用tkmy_strcpy

問題是你沒有足夠的內存。超出有效限制使用內存會導致未定義的行爲。

使用類似:

char temp_key[1000] = ""; // Make the size large enough for 
          // the kinds of strings you are 
          // expecting to see. 

同樣,使用:

char temp_value[1000] = ""; 
+0

這對我來說很愚蠢。我認爲tk和temp_key指向不同的mem位置,我可以爲tk添加儘可能多的內容。還有很多要學習。 – user3275095

+0

@ user3275​​095,不要太難受。大部分使用過程中都犯了相當愚蠢的錯誤。 –