我可以检查指针是否已分配给malloc以外的其他内容吗?

时间:2012-10-31 18:50:42

标签: c pointers null malloc string

设置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)

5 个答案:

答案 0 :(得分:4)

你似乎对malloc()做什么以及NULL的作用感到有点困惑。

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

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

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

strcpy(string, "Hello World");

现在你可以安全地做到:

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

在初始化之前,读取内存并不“安全”;你无法保证你会发现什么。你的程序不会崩溃,但你看到的就是你得到的东西。

您还可以安全地使用:

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

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


你问:

  

如何通过stringstrcpy()或...

等方式检查strcat()是否已被更改

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

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()会声称为您分配内存,但您可能会发现当您访问它时,它毕竟不可用。

答案 1 :(得分:1)

您无法以可靠的跨平台方式。为什么不将malloc()返回的内存初始化为全零?然后你可以看看它是否已被更改。

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

答案 2 :(得分: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,因此如果发生这种情况,您的字符串不会更改。

答案 3 :(得分:0)

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

char *string = malloc(500);之后

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

答案 4 :(得分:0)

将指针视为整数变量,其值为内存地址。因此,如果指针为空,则意味着变量的实际值是不存在的地址null(由值0表示)。 / p>

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

现在鉴于变量p本身有来处理此地址后面的任何内存插槽(C语言中为p*)是否发生变化。