修剪char*中的前n个字符并释放它

修剪char*中的前n个字符并释放它,c,pointers,char,trim,C,Pointers,Char,Trim,现在我想从左边修剪5个字符 int length = 12; char *filename; char *key; filename = (char *)calloc(length, sizeof(char)); strcpy(filename, "Hello World");//filename = "Hello World\0"; 我可以使用memcpy或strcpy实现这一点,但我可以用上面的方法实现吗 这是错误的: key = filename + 6; *(filename + 5

现在我想从左边修剪5个字符

int length = 12;
char *filename;
char *key;

filename = (char *)calloc(length, sizeof(char));
strcpy(filename, "Hello World");//filename = "Hello World\0";
我可以使用memcpy或strcpy实现这一点,但我可以用上面的方法实现吗

这是错误的:

key = filename + 6;
*(filename + 5) = 0;

free(filename);

printf("%s\n", key);
printf("%s\n", filename); //No Segmentation Fault Why??
至于无segfault部分,未定义的行为可能不会立即表现出来:例如,当您释放错误的区域时,释放本身可能会工作,但后续的分配可能会失败

如果要缩短字符串,请复制并释放原始字符串:

// 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);
通常,您只能释放已分配的资源。主要原因是
malloc
/
calloc
/
realloc
在与返回给您的地址相关联的内存中,通常位于分配地址之前的块中。你可以试着假装它,但即使它起作用,解决方案也会很脆弱且不可移植。

这是错误的:

key = filename + 6;
*(filename + 5) = 0;

free(filename);

printf("%s\n", key);
printf("%s\n", filename); //No Segmentation Fault Why??
至于无segfault部分,未定义的行为可能不会立即表现出来:例如,当您释放错误的区域时,释放本身可能会工作,但后续的分配可能会失败

如果要缩短字符串,请复制并释放原始字符串:

// 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);

通常,您只能释放已分配的资源。主要原因是
malloc
/
calloc
/
realloc
在与返回给您的地址相关联的内存中,通常位于分配地址之前的块中。您可以尝试假装它,但即使它有效,解决方案也会很脆弱且不可移植。

即使您使用strcpy()或strncpy()将文件名初始化为“Hello World”来解决内存超前问题,最后一行仍然会出现seg错误,因为您正在释放先前为上面的文件名2行分配的堆内存。将free()移动到最后,您会相对良好

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!
#包括
#包括
#包括
int main(int argc,字符**argv)
{
整数长度=12;
字符*文件名;
字符*键;
filename=(char*)calloc(长度,sizeof(char));
strcpy(文件名为“Hello World”);
key=filename+6;
*(文件名+5)=0;
printf(“%s\n,key”);
printf(“%s\n”,文件名);//没有分段错误为什么??
免费(文件名);
}

即使通过使用strcpy()或strncpy()将文件名初始化为“Hello World”来清除内存超前问题,您的最后一行仍然会出现seg错误,因为您正在释放先前为上述文件名2行分配的堆内存。将free()移动到最后,您会相对良好

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!
#包括
#包括
#包括
int main(int argc,字符**argv)
{
整数长度=12;
字符*文件名;
字符*键;
filename=(char*)calloc(长度,sizeof(char));
strcpy(文件名为“Hello World”);
key=filename+6;
*(文件名+5)=0;
printf(“%s\n,key”);
printf(“%s\n”,文件名);//没有分段错误为什么??
免费(文件名);
}

filename=“Hello World\0”泄漏上面一行上分配的内存<代码>*(文件名+5)=0是未定义的行为,就像
自由(文件名)一样。这不一定会坏,但它坏了。无论如何,
free
不是以null结尾的。将
*(filename+5)
设置为0不会阻止它释放字符串的其余部分。如果我正确解释了问题的标题,您想要的是
仅释放部分已分配内存的一部分,保留其余部分?这是不可能的。好吧,一些实现可能会给您提供内存分配功能的挂钩,使之成为可能,但这只是理论。没有远程可移植的方法。@botchedDevil不,它不会工作。如果您确切地知道malloc机制在实现中是如何工作的,那么您可能能够破解一些东西来“使其工作”,但即使这是可能的,99.999%的时间里这是个坏主意。@botchedDevil“free如何知道要释放的内存长度?”这是一个极好的问题!以下是(提示:
malloc
/
calloc
给它留下了一些提示)。
filename=“Hello World\0”泄漏上面一行上分配的内存<代码>*(文件名+5)=0是未定义的行为,就像
自由(文件名)一样。这不一定会坏,但它坏了。无论如何,
free
不是以null结尾的。将
*(filename+5)
设置为0不会阻止它释放字符串的其余部分。如果我正确解释了问题的标题,您想要的是
仅释放部分已分配内存的一部分,保留其余部分?这是不可能的。好吧,一些实现可能会给您提供内存分配功能的挂钩,使之成为可能,但这只是理论。没有远程可移植的方法。@botchedDevil不,它不会工作。如果您确切地知道malloc机制在实现中是如何工作的,那么您可能能够破解一些东西来“使其工作”,但即使这是可能的,99.999%的时间里这是个坏主意。@botchedDevil“free如何知道要释放的内存长度?”这是一个极好的问题!这里是(提示:
malloc
/
calloc
给它留下了一点提示)。好吧,使用
free
d内存是未定义的行为,它不需要segfault,它完全可以假装工作(星期二除外)。好吧,使用
free
d内存是未定义的行为,它不需要segfault,它完全可以假装工作(星期二除外)。“不!!!你刚刚泄露了以前分配的内存块!”我理解这一点,但当我指向函数中的字符串文字时,意味着我指向加载函数中的内存块,因此,只要函数加载到内存中,我的指针就可以正常工作(尽管函数卸载不会在程序执行期间发生)。“那么,我在这里想的方向对吗?”博切德维尔第一个作业的问题不是什么