int length = 12;
char *filename;
char *key;
filename = (char *)calloc(length, sizeof(char));
strcpy(filename, "Hello World");//filename = "Hello World\0";
现在我想从左边修剪5个字符
key = filename + 6;
*(filename + 5) = 0;
free(filename);
printf("%s\n", key);
printf("%s\n", filename); //No Segmentation Fault Why??
我可以使用memcpy或strcpy来实现这个目的但是我可以用上面的方法吗?
答案 0 :(得分:4)
这是错的:
// So far so good...
filename = (char *)calloc(length, sizeof(char));
// No!!! You just leaked the previously allocated memory block!
// The `\0` at the end is also wrong.
filename = "Hello World\0";
// This is OK
key = filename + 6;
// You are writing into memory of a string literal, that's undefined behavior
*(filename + 5) = 0;
// You are freeing a string literal, that's undefined behavior too
free(filename);
至于没有段错误部分,未定义的行为可能不会立即显现出来:例如,当您释放错误的区域时,释放本身可能会起作用,但后续分配可能会失败。
如果您想缩短字符串,请复制并释放原始字符:
char *filename = malloc(length); // no cast
strcpy(filename, "Hello, world"); // no \0
char *trimmed = strdup(filename+6); // Make a copy
free(filename); // Free the original
filename = trimmed; // You are done!
一般情况下,您只能释放已分配的内容。造成这种情况的主要原因是与返回给您的地址关联的内存中的malloc
/ calloc
/ realloc
store "bookkeeping" information,通常位于分配地址之前的块中。您可以尝试伪造它,但即使它起作用,解决方案也将是脆弱且不可移植的。
答案 1 :(得分:0)
即使你使用strcpy()或strncpy()将文件名初始化为" Hello World"来清理内存引导问题,你仍然会在最后一行上遇到段错误,因为你&# 39;重新释放先前为上面的文件名2行分配的堆内存。将你的免费()移到最后,你会相对很好。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
int length = 12;
char *filename;
char *key;
filename = (char *)calloc(length, sizeof(char));
strcpy(filename, "Hello World");
key = filename + 6;
*(filename + 5) = 0;
printf("%s\n, key");
printf("%s\n", filename); //No Segmentation Fault Why??
free(filename);
}