我不知道当我为5分配内存时它会打印出OneExample。 我知道可以使用strncpy做到这一点 但是有没有办法不用strncpy
它可以与strncpy一起使用,但是有没有办法在没有strncpy的情况下做到这一点?
void main()
{
char *a;
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
}
它打印出OneExample
是否应打印OneE? 有人可以解释吗?
void main()
{
char *a;
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
}
答案 0 :(得分:4)
您没有在使用分配的内存。分配内存后,使用指向字符串文字的指针覆盖指针a
,从而导致内存泄漏。后续对free
的调用也可能会使您的应用程序崩溃,因为您是在未分配free
的指针上调用malloc
。
如果要使用分配的空间,可以将其复制到其中(例如,使用strncpy
)。
答案 1 :(得分:2)
我不知道当我为5分配内存时它会打印出OneExample。我知道可以使用strncpy来做到这一点,但是有没有办法不用strncpy来做到这一点
它可以与strncpy一起使用,但是有没有办法在没有strncpy的情况下做到这一点?
您可以使用memcpy()
作为替代。
阅读memcpy()并检查this。
似乎您对C语言中的指针有误解。
查看代码的这一部分:
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
您正在将内存分配给char
指针a
,然后立即将其指向字符串文字OneExample
。
这是代码中的内存泄漏,因为您丢失了分配的内存的引用。
您应该注意free()
会释放先前由malloc()
,calloc()
或realloc()
分配的空间,否则行为是不确定的。
在您的程序中,您尝试释放字符串文字"OneExample"
的内存,这将导致未定义的行为。
使用memcpy()
,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char *a = malloc(5);
if (a == NULL) {
fprintf (stderr, "Failed to allocate memory\n");
exit(EXIT_FAILURE);
}
memcpy (a, "OneExample", 4); // copy 4 characters to a, leaving space for null terminating character
a[4] = '\0'; // make sure to add null terminating character at the end of string
printf("%s\n",a);
free(a);
return 0;
}
其他:
使用void
作为main
函数的返回类型不符合标准。主函数的返回类型应为int
。
遵循良好的编程习惯,请始终检查malloc返回。
答案 2 :(得分:2)
#include <stdlib.h>
(未在代码中显示)。原因是malloc具有返回void *
的原型,而没有该原型,则编译器将假定其返回int
。在64位体系结构中,这是个问题,因为void *
是64位类型,而int
是32位。这使得提取malloc()
返回的值的代码仅占用结果的32个少显着位,然后将它们转换为指针(按照您的类型转换,您不应该- -对此有很多评论-,您将避免应该尝试将int
值转换为char *
而无需强制转换的错误)在将malloc(3)
给定的指针分配给a
之后,用字符串文字"OneExample"
的地址覆盖该指针。这有两件事:
malloc(3)
给定的指针值,该指针值存储在a
中,因此您将不再拥有它,并且将永远无法free(3)
。这称为内存泄漏,您应避免这些,因为它们是编程错误。free(3)
的调用中做出某种未定义的行为,该行为仅接受malloc
先前返回的指针值作为参数(并且这不是存储在{{1中的实际地址) }})可能您遇到了a
个中断,并且此调用导致程序崩溃。当您对SIGSEGV
进行分配时,您只是在更改存储在其中的指针值,而不是更改延迟的内存内容,因此调用a
才有意义,因为这是唯一的方法是在周围复制字符串。或者,您可以一一复制字符,如下所示:
strcpy(3)
最后一步是什么使得有必要在char *a = malloc(5); /* this makes a memory buffer of 5 char available through a */
int i;
for(i = 0; i < 4 /* see below */; i++)
a[i] = "OneExample"[i]; /* this is the copy of the char at pos i */
a[i] = '\0'; /* we must terminate the string if we want to print it */
而不是for
时运行i < 4
循环,因为我们要求i < 5
输入五个字符,并且必须包含字符串终止符char。
有一个标准库可供选择,它是:
malloc()
等效于:
char *a = strdup("OneExample");
但是如果您想通过将字符串截断为5来解决示例,则可以执行以下操作:
#define S "OneExample"
char *a = malloc(strlen(S) + 1); /* see the +1 to allow for the null terminator */
strcpy(a, S);
,您可以将其称为:
char *dup_truncated_at(const char *s, int at)
{
char *result = malloc(at + 1); /* the size we need */
memcpy(result, s, at); /* copy the first at chars to the position returned by malloc() */
result[at] = '\0'; /* and put the string terminator */
return result; /* return the pointer, that must be freed with free() */
}
答案 3 :(得分:0)
首先在这里
if(isset($_POST['attended'])) {
....
}
if(isset($_POST['attended2'])) {
...
}
您已经从堆中立即分配了a=(char*)malloc(5);
个字节的内存
5
使用字符串文字a="OneExample";
的基地址覆盖以前的动态内存,原因是"OneExample"
不再指向任何动态内存,它会导致内存泄漏(因为没有对象指向动态内存,它丢失了),甚至在那之后
a
释放非动态分配的内存会导致不确定的行为。
旁注,请务必阅读Why does malloc allocate more memory spaces than I ask for和Malloc vs custom allocator: Malloc has a lot of overhead. Why?以获得有关free(a);
的更多信息。
答案 4 :(得分:0)
您需要清楚指针所指向的内容。首先,您声明一个char *a;
。这是指向字符的指针。
在a=(char*)malloc(5);
行中,您用malloc
分配了一点内存,并将该内存的位置分配给指针a
。 (有点口语,但您明白我的意思)。因此,a
现在指向5个字节的新分配内存。
接下来,a="OneExample";
。 a
得到一个新值,即字符串OneExample
的位置;现在不再有指向分配的五个字节的指针。他们现在是孤儿。 a
指向静态上下文中的字符串。根据体系结构,编译器和许多其他事物,这可能是静态数据空间,程序空间或类似的东西。至少不是用于变量的内存的一部分。
因此,当您执行printf("%s",a);
时,a
指向字符串,而printf
将打印出字符串(完整的字符串)。
当您执行free(a);
时,您试图释放程序,数据等空间的一部分。也就是说,通常是不允许的。您应该收到一条错误消息;在Linux中将是这样的:
*** Error in `./try': free(): invalid pointer: 0x000000000040081c ***
======= Backtrace: =========
/lib64/libc.so.6(+0x776f4)[0x7f915c1ca6f4]
/lib64/libc.so.6(+0x7ff4a)[0x7f915c1d2f4a]
/lib64/libc.so.6(cfree+0x4c)[0x7f915c1d6c1c]
./try[0x400740]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7f915c1737d0]
./try[0x4005c9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 21763273 /home/ljm/src/try
00600000-00601000 r--p 00000000 08:01 21763273 /home/ljm/src/try
00601000-00602000 rw-p 00001000 08:01 21763273 /home/ljm/src/try
[- more lines -]
答案 5 :(得分:0)
语句a="OneExample";
并不意味着“将字符串"OneExample"
复制到a
中。”
在C语言中,像"OneExample"
这样的字符串文字是编译器为您分配的char
数组。在表达式中使用该数组时,该数组将自动成为指向其第一个元素的指针。 1
所以a="OneExample"
的意思是“将指针a
设置为指向char
中的第一个"OneExample"
。”
现在,a
指向字符串,printf
当然会打印它。
然后free(a)
是错误的,因为它试图释放"OneExample"
的内存,而不是释放提供的malloc
的内存。
1 当字符串文字是sizeof
的操作数,一元&
的操作数或用于初始化数组时,不会发生此自动转换。
答案 6 :(得分:0)
=
不会复制字符串,只是将新值分配给覆盖旧值的指针。您需要分配足够的内存来存储字符串,然后将其复制到分配的空间中
#define MYTEXT "This string will be copied"
char *a = malloc(strlen(MYTEXT) + 1); //+1 because you need to store the trailing zero
strcpy(a,MYTEXT);
然后您可以在不再需要的时候释放a