我很想知道在字符串周围保留元数据标题是否安全且不依赖于实现?
我不确定以下内容是否适用于跨平台,或者是否有某些内容可能会导致错误的size
或total
字段读取,或者是否会出现问题缓冲区上realloc
?
#include <stdlib.h>
#include <stdio.h>
typedef struct{
int size;
int total;
char buf[];
} String;
int get_str_size(char *str){
String *pointer = (void*)(str-sizeof (String));
return pointer->size;
}
int get_str_total(char *str){
String *pointer = (void*)(str-sizeof (String));
return pointer->total;
}
char *init_string(int sz){
size_t header_size = 1 + sz + sizeof(String);
String *pointer = calloc(header_size, 1);
pointer->total = 0;
pointer->size = sz;
return pointer->buf;
}
char *realloc_string(char *str, int sz){
int old = get_str_size(str);
int new = old + sz;
String *pointer1 = (void*)(str-sizeof (String));
size_t header_size = 1 + new + sizeof(String);
String *pointer2 = realloc(pointer1, header_size);
return pointer2->buf;
}
int main(void){
char *str = NULL;
str = init_string(10);
printf("Length of str:%d\n", get_str_size(str));
printf("Total malloc'd:%d\n", get_str_total(str));
free(str - sizeof (String));
return 0;
}
答案 0 :(得分:1)
这不安全。
它没有未定义的行为(UB),也没有实现定义的行为,因为 legal ,除了轻微的int/size_t
问题。
不幸的是,代码隐藏得太多了。 @Jonathan Leffler。请考虑以下编译的代码,然后调用UB。
printf("%d\n", get_str_size("Hello Word"));
使用类型String
作为参数而不是char *
,函数集会更好。这就是类型检查的目的。
小问题。
C 字符串是数组。使用类型size_t
最好使用数组索引。 int
可能过于狭窄。
String *String_copy(const char *src) {
size_t len = strlen(src);
// v-v Overflow potential
String *dest = init_string(len);
...
return dest;
}
以下可能 int
溢出。重新命令以防止。
// v----v int math
// size_t header_size = 1 + sz + sizeof(String);
size_t header_size = sz + sizeof(String) + 1;
// or
size_t header_size = sizeof(String) + sz + 1;
代码缺少应该补充集合的其他函数。 @Ian
缺少错误检查,但假设这是为了简化代码显示。