如何清除C中的内存?

时间:2016-03-09 19:44:12

标签: c arrays pointers srand

我编写了一个生成随机字符串的程序, 但是当我调用该函数两次/多次时,我得到相同的随机字符串。

请检查以下代码:

#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

2 个答案:

答案 0 :(得分:4)

函数srand设置随机种子,如果再次使用相同的随机种子调用它,它将导致将来的随机调用返回相同序列的重复。所以当你打电话时:

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

它将随机种子重置为中的挂钟时间。这意味着如果你在不到一秒的时间内再次调用它(就像在代码中那样),它可能会将种子重置为相同的值,从而导致你再次获得相同的随机字符串。

在调用任何其他调用srand

的函数之前,您应该只在主程序的开头调用rand 一次

答案 1 :(得分: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)保证在C中为1。

  3. 编写分配语句的更好,更健壮的方法是

    c =  calloc( len1, sizeof*c );