是否可以 free() 或缩短 char 数组?

Is it possible to free() or shorten an char array?

是否可以 free() 非动态内存?

我有一个长度为 10 的字符数组。我有 4 个不需要的零。 有没有办法 trim 最后四个零并缩短数组大小?或者是将值复制到缩短数组的唯一方法

char arr[10]={2,8,2,1,7,1,0,0,0,0}

//NON WORKING CODE! just showing the concept
//The shortArr function dosen't work because i have to pre-declare the size

char * shortArr(char * arr){
 unsigned long len = strlen(arr); 
 static char shortArr[len]; //<--- Variable length array declaration cannot have 'static' storage duration
 memcpy(shortArr, arr, len);
    
 return &shortArr;
};

shortArr();

基本上我在做什么

unsigned char arr[10]={2,8,2,1,7,1,0,0,0,0}
unsigned char shortArr[strlen(arr)]; 
/*creating a size of 6 by removing the las 0,0,0,0 , 
all do it is quite dangerous to use with strlen since it stops at the first encountering with a zero 
what if the arr had a zero in between the first 7 bytes
arr[10]={2,8,0,1,7,1,0,0,0,0} then only (2,8) would be kept and
and the size would be of 2
*/
memcpy(copyOfArr,arr,sizeof(shortArr)); // copying the bytes from arr to shortArr

Is it possible to free() a non dynamically memory?

您不应将 malloc 或相关例程未返回的地址传递给 freefree 的行为在 C 2018 7.22.3.3 中指定。第 2 段说:

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

您可以定义一个函数来帮助计算您想要的数组的新长度。此函数基本上会计算等于 '[=12=]'.

的尾随字节数
unsigned trimmedlen (unsigned char arr[], unsigned arrlen) {
    unsigned newlen = arrlen;
    for (i = 0; i < arrlen; ++i) {
        if (arr[arrlen - i - 1] != '[=10=]') break;
        --newlen;
    }
    return newlen;
}

现在,您可以使用 VLA 创建新数组(假设您的编译器支持它)。

unsigned char newarr[trimmedlen(arr, sizeof(arr))];
memcpy(newarr, arr, sizeof(newarr));

如果您知道您希望数组有多短,那么您可以简单地这样做:

#define ELEM_COUNT 20
char arr[ELEM_COUNT];

#undef ELEM_COUNT
#define ELEM_COUNT 10 //just ignore that in reality, arr has 20 elements

如果您在运行时不知道它,则只需将其存储为运行时值。简单!

//with VLAs
size_t size = 20;
char arr[size];
size = 10;

同样,忽略其他元素存在的事实。大多数时候,您在循环中访问数组:

for (size_t i = 0; i < size; i++) {
    printf("%c\n", arr[i]);
}

因此,要减少数组,您所要做的就是减少 size 变量。这不会浪费内存,因为它的数量太少了。如果浪费了 10 个字节,则什么也不会发生。如果是大数组,就不要在栈上分配。