2016-03-09 67 views
1

我寫了一個程序來生成一個隨機字符串, 但是當我調用兩次/多次的函數,我得到相同的隨機字符串。如何清除C中的內存?

請檢查下面的代碼:

#include <string.h> 
#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 

char* randomstring(int length); 

int main() 
{ 
    char* randomstring(int); 
    char *str, *str2; 
    str = randomstring(3); 
    str2 = randomstring(3); 
    printf("final random string is %s and length is %s\n", str, str2); 
} 

char* randomstring(int length) 
{ 
    int len, len1, i = 0, j = 0; 
    char *c; 
    char *string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    len = strlen(string); 
    len1 = length + 1; 
    time_t t; 
    c=(char*) calloc(len1, sizeof(char)); 
    printf("final random string is %d \n", len); 
    srand((unsigned) time(&t)); 
    for(i = 0; i < length; i++) 
    { 
     j=rand() % len; 
     c[i] = string[j]; 
    } 
    c[len1] = '\0'; 
    return c; 
} 

輸出:

final random string is 26 
final random string is 26 
final random string is BNQ and length is BNQ 
+0

[請參閱爲什麼不投的malloc'的返回值這個討論( )'和家庭在'C'。](http://stackoverflow.com/q/605845/2173917)。 –

+0

在開始處移動'char * randomstring(int);'...... –

+3

從現在開始,請正確縮進您的代碼,否則沒有人能夠讀取它。 – birdoftheday

回答

1

首先,對於像分配

c=(char*) calloc(len1,sizeof(char)); 

後,使用

c[len1]='\0'; 

正在訪問超出限制的內存。它調用undefined behavior

爲了詳細說明,C使用基於0的索引,所以,說

c[len1]='\0'; 

你會off-by-one

然後,您應該只撥打PNRG播種機功能srand()一次,可能在main()。否則,time()具有1秒的粒度,它將種子具有相同值的PNRG,這又將導致rand()再次產生相同組的隨機數字。

這就是說,

  1. Please see this discussion on why not to cast the return value of malloc() and family in C.

  2. sizeof(char)是保證1 C.

寫分配語句的更好,穩健的方式將

c = calloc(len1, sizeof*c);  
4

srand將隨機種子的功能,如果你用相同的隨機種子再次調用它,它會導致將來的隨機調用返回相同序列的重複。所以,當你撥打:

srand((unsigned) time(&t)); 

它重置在的隨機種子掛鐘時間。也就是說,如果在經過不到一秒鐘後再次調用它(如同在代碼中那樣),它可能會將種子重置爲相同的值,導致您再次獲得相同的隨機字符串。

你應該只調用srand一次,在你的主程序啓動,調用,調用任何其它函數之前rand

+0

如果我刪除srand函數,那麼它會給出正確的輸出? –

+0

如果你完全刪除'srand',隨機數發生器將被播種爲0.所以它會給出「正確的」輸出,但每次運行程序時都會給出相同的輸出。每次運行程序時,將'srand'調用放在'main'中會導致不同的輸出(假設時鐘在運行間隔至少一秒鐘) –