Is it safe to store metadata up to the malloc'd string in C?

I am curious to know if keeping the metadata header around the string will be safe and not implementation dependent?

I am not sure that the following works will work on different platforms either if there is something that can lead to incorrect fields sizeor totalor if there is a problem with reallocthe buffer

#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;
}
+4
source share
1 answer

It's not safe.

It does not have undefined (UB) behavior, and the behavior defined by the implementation definition is legal, except for a minor issue int/size_t.

, . @ . , , 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

, , .

+1

Source: https://habr.com/ru/post/1662564/


All Articles