2016-03-09 2 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

[Пожалуйста, смотрите эту дискуссию о том, почему не бросить возвращаемое значение 'таНос () 'и семью в' 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 = calloc(len1, sizeof*c);  
4

Функция srand устанавливает случайное семя, и если вы вызываете его снова с одним и тем же случайным семенем, это приведет к тому, что будущие случайные вызовы возвращают повторение одной и той же последовательности. Так что, когда вы звоните:

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

он сбрасывает случайное зерно в то время настенных часов в секундах. Это означает, что если вы вызовете это снова через несколько секунд (как и в вашем коде), он, вероятно, сбрасывает семя к тому же значению, заставляя вас снова получить одну и ту же случайную строку.

Вы должны вызывать только srandраз, в начале вашей программы в основном, перед вызовом любой другой функции, которая вызывает rand

+0

если я удалю функцию srand, так это даст правильный результат? –

+0

Если вы полностью удалите 'srand', генератор случайных чисел будет засеян 0. Таким образом, он даст« правильный »вывод, но будет давать тот же результат каждый раз, когда вы запускаете программу. Помещение вызова 'srand' в' main' будет приводить к разному выходу каждый раз, когда вы запускаете программу (при условии, что часы будут тикать не менее одной секунды между прогонами) –

Смежные вопросы