【发布时间】:2010-03-26 17:01:07
【问题描述】:
我刚刚开始为 uni 分配任务,这对我提出了一个问题。
我不明白如何在没有内存泄漏的情况下从函数返回字符串。
char* trim(char* line) {
int start = 0;
int end = strlen(line) - 1;
/* find the start position of the string */
while(isspace(line[start]) != 0) {
start++;
}
//printf("start is %d\n", start);
/* find the position end of the string */
while(isspace(line[end]) != 0) {
end--;
}
//printf("end is %d\n", end);
/* calculate string length and add 1 for the sentinel */
int len = end - start + 2;
/* initialise char array to len and read in characters */
int i;
char* trimmed = calloc(sizeof(char), len);
for(i = 0; i < (len - 1); i++) {
trimmed[i] = line[start + i];
}
trimmed[len - 1] = '\0';
return trimmed;
}
如您所见,我正在返回一个指向 char 的指针,它是一个数组。我发现如果我尝试通过以下方式制作“修剪”数组:
char trimmed[len];
然后编译器会抛出一条消息,指出在这一行上需要一个常量。我认为这意味着由于某种原因,您在初始化数组时不能使用变量作为数组长度,尽管有些事情告诉我这是不对的。
因此,我通过将一些内存分配给 char 指针来创建数组。
我知道这个函数对于它试图做的事情可能是次优的,但我真正想知道的是:
-
你可以正常初始化一个数组使用一个变量来声明长度吗:
字符修剪[len];
如果我有一个该类型的数组(char trimmed[]),它的返回类型是否与指向 char 的指针(即 char*)相同。
如果我通过分配一些内存并将其分配给一个 char 指针来创建我的数组,我该如何释放这些内存。在我看来,一旦我返回了这个数组,我就无法访问它来释放它,因为它是一个局部变量。
【问题讨论】:
-
“我认为这意味着由于某种原因你不能在初始化数组时使用变量作为数组长度,尽管有些事情告诉我这是不对的。”不,这是正确的,数组大小必须是编译时常量。
-
+1 用于跟进某个主题,即使您知道它“足以胜任 [您的] 任务”
-
这并没有具体回答您的问题,但这种情况下的另一种选择是就地修剪字符串。这是可能的,因为修剪操作永远不会增加字符串的长度。显然,需要修改使用您的方法的代码以处理此更改。
-
正如 Neil 在他的回答中指出的那样,detly 的评论对于现代 C 来说是错误的。C99 标准允许在数组声明中使用变量。所以它是有效的代码。但是,许多编译器默认为 C89 模式,以防万一您希望您的代码在 DEC VAX 或其他设备上编译。这可能就是您收到错误的原因。
-
我认为杰弗里的回答是最优雅的。这将导致为字符串对象持有的字符串分配所有原始内存,但在正常使用中似乎不太可能有很多空白,即没有很多浪费。
标签: c