0

char *指针设置为 后malloc(size),有没有办法检查它是否仍未更改?我认为指向未分配空间的指针将评估为NULL但显然不是:

char *string = malloc(500);
if(string==NULL) puts("Hello World");
else puts("It's not null");

我认为这应该输出"Hello World",但事实并非如此。我如何检查字符串是否被类似的东西改变了,strcpy()或者strcat(),甚至与我自己的项目更相关,通过:

fgets(string, 499, fr)
4

5 回答 5

4

您似乎对malloc()NULL 的作用和作用有些困惑。

malloc()函数分配空间,但不将空间初始化为任何值。from 的返回值malloc()是指向该空间(的第一个字节)的指针。除非您尝试分配零字节1 ,否则如果它无法分配与您要求的一样多的空间2,则 from 的返回值malloc()只会是 NULL 。

因此,除非您的系统内存非常不足,否则您的程序不会打印“Hello World”。指针string将是一个有效的内存位置。

完全未定义的是string指向的数据。您必须以某种方式对其进行初始化,例如,使用:

strcpy(string, "Hello World");

现在您可以安全地执行以下操作:

printf("%s!\n", string);

在初始化之前,读取内存是不“安全的”;无法保证您会在其中找到什么。您的程序不会崩溃,但所见即所得。

您还可以安全地使用:

if (fgets(string, 500, stdin) != 0)
    printf("Read: %s", string);

注意fgets()为终端预留空间'\0';您不必将空间缩小一个。


你问:

我如何检查是否string已被类似strcpy()orstrcat()或 ...

对于大多数实际目的,您无法确定它是否已被修改,因为内存没有定义的内容。如果你真的想知道,你可能会这样做:

char *string_copy = malloc(500);
if (string_copy != NULL)
    memmove(string_copy, string, 500);

复制分配的内存的原始内容,然后使用:

if (memcmp(string_copy, string, 500) != 0)
   ...someone changed either string or string_copy (or both)...

这是相当薄的冰;分配空间中的值没有定义,但在实践中,我会惊讶地发现它不起作用。另一方面,我想不出我会对这种知识感兴趣的情况。如果我分配内存,是为了使用它——通常几乎是立即使用。


1如果您分配零字节,您将获得两种实现定义的行为之一。要么你得到一个返回的 NULL 指针,要么你得到一个有效的、非 NULL 指针,指向与任何其他内存分配不同的零字节可访问内存(因此你不能安全地访问)。无论哪种方式,结果都可以安全地传递给free(). 如果您分配零字节,则任何通过返回的指针访问内存的尝试都会导致未定义的行为。

2请注意,在Linux上,你可以要求大量内存,malloc()并声称会为你分配,但你可能会发现,当你访问它时,它根本不可用。

于 2012-10-31T18:57:26.773 回答
1

你不能以一种可靠的、跨平台的方式。为什么不将返回的内存初始化malloc()为全零呢?然后你可以看看它是否被改变了。

在您的示例中,您正在测试指针本身的值,它将指向分配的内存。malloc()除非失败,否则不能为空。

于 2012-10-31T18:52:39.550 回答
1

After setting a char * pointer to malloc(size), is there a way to check if it's still not been changed?

  • 是的,几乎你在做什么,但你需要将指针指向NULL. 然后你就会知道它是否被NULL你的代码改变了。

I thought that a pointer to unassigned space would evaluate to NULL

NULL不,当您将其设置为时,指针的计算结果为NULL

char *string = NULL;
if(string==NULL) puts("Hello World"); //Will execute this
else puts("It's not null");

string = malloc(500);  //Assuming this was successful

if(string==NULL) puts("Hello World");
else puts("It's not null");  //Now we'll execute this

I think this should output "Hello World" but it doesn't

  • 对,因为它不是NULL一个有效的指针值(假设malloc()是成功的)

How can I check if string has been changed by something like strcpy() or strcat() or fgets()

  • 您无法从指针值中检查这一点,您需要自己跟踪字符串何时更改。fgets()NULL在失败的情况下返回,所以如果发生这种情况,你的字符串不会改变。
于 2012-10-31T19:10:07.287 回答
0

这话是谁说的,I thought that a pointer to unassigned space would evaluate to NULL but apparently not

char *string = malloc(500);

string指向该分配空间的第一个字节或heap(除非分配以某种方式失败)因此您的string指针不是NULL.

于 2012-10-31T18:56:20.357 回答
0

将指针视为整数变量,其值为内存地址,因此如果指针为空,则表示该变量的实际值为不存在的地址空(由值 0 表示)。

当您编写类似char *p = (char *)malloc(100);您要求的内容时,编译器会找到 100 个字节的未使用空间并将 p 的值设置为该空间中第一个字节的地址。现在变量有一个值并且它不是 Null。

现在鉴于变量 p 本身与该地址之后的任何内存插槽(用 C 术语)是否更改无关p*

于 2012-10-31T19:00:40.377 回答