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

时间:2013-06-22 14:24:36

标签: c pointers char trim

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来实现这个目的但是我可以用上面的方法吗?

2 个答案:

答案 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);
}