[英]Pointer difference and size_t
我想分配内存来保存从给定字符串中提取的字段。 字段的大小由两个指针的差异决定,请参阅以下最小示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
const char line[] = "foo,bar,baz";
char *field_start = line;
char *field_end;
char *field;
field_end = strchr(line, ',');
field = malloc(field_end - field_start + 1);
memcpy(field, field_start, field_end - field_start);
*(field + (field_end - field_start)) = '\0';
printf("field=\"%s\"\n", field);
/* ... */
return (0);
}
使用clang -Weverything -o ex ex.c
编译此代码clang -Weverything -o ex ex.c
产生以下警告:
ex.c:14:41: warning: implicit conversion changes signedness: 'long' to 'unsigned long'
[-Wsign-conversion]
field = malloc(field_end - field_start + 1);
~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~^~~
ex.c:15:39: warning: implicit conversion changes signedness: 'long' to 'unsigned long'
[-Wsign-conversion]
memcpy(field, field_start, field_end - field_start);
~~~~~~ ~~~~~~~~~~^~~~~~~~~~~~~
据我了解,指针差异的结果是ptrdiff_t类型,而malloc / memcpy期望一个类型为size_t的参数。 所以我的问题是如何解决这个问题并消除警告? 由于field_end >= field_start
,差异不能变为负数,因此上述内容可以安全地转换为size_t
field = malloc(size_t(field_end - field_start + 1));
memcpy(field, size_t(field_start, field_end - field_start));
或者是我忽视的任何问题?
注意:
为简单起见,上面没有检查返回值。 field_start和_end当然应该是const。
field_end >= field_start
仅在strchr
不返回NULL
情况下保持,即类型系统中没有任何内容告诉编译器这确实总是成立。 因此警告是有道理的。 但是,如果你确定不是这种情况,那么(size_t)(field_end - field_start)
应该没问题。 为了不重复这一切,我补充说
size_t field_len;
/* memchr & null-check go here */
field_len = (size_t)(field_end - field_start);
...然后全部使用field_len
。
话虽这么说,您可能想要通过调用strndup
来替换malloc
/ memcpy
组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.