c - 如何在 memmove 后释放 malloced 指针
问题描述
解决方案
显然,根据free(a) 和 memset(a, 0, malloced_size) 之间的区别(实际标题是“c 中的自由函数”但我觉得不够具体),我需要将数据 memset 为 0在我释放它以实际释放它之前/之后,就好像它从未分配过任何数据一样
更新:固定
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdio.h>
uintptr_t round_up(uintptr_t value, uintptr_t size)
{
fprintf(stderr, "called round_up\nreturning %p\n", (void *) (value ? size * ((value + (size - 1)) / size) : size));
return value ? size * ((value + (size - 1)) / size) : size;
}
int read_fast_verify(const char *src, int len_of_source, char **dest, char ** a, int requested_len) {
*a = malloc(requested_len+4096);
if (len_of_source < requested_len) memcpy(*a, src, len_of_source);
else memcpy(*a, src, requested_len);
*dest = memmove((void *)round_up((uintptr_t)*a, 4096), src, requested_len);
return requested_len;
}
void __lseek_string__(char **src, int len, int offset) {
memmove(*src, *src+offset, len);
}
char * string1 = "hello";
char * string2;
char * s;
int main(void) {
read_fast_verify(string1, strlen(string1), &string2, &s, (strlen(string1) + 5));
__lseek_string__(&string2, strlen(string1), 5);
free(s);
}
问题
如何在 memmove 后释放 malloced 指针,因为如果我使用 NULL dest 作为它的返回值(例如 char * dest = memmove(...);),memmove 似乎会出现段错误
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdio.h>
uintptr_t round_up(uintptr_t value, uintptr_t size)
{
fprintf(stderr, "called round_up\nreturning %p\n", (void *) (value ? size * ((value + (size - 1)) / size) : size));
return value ? size * ((value + (size - 1)) / size) : size;
}
int read_fast_verify(const char *src, int len_of_source, char **dest, char ** a, int requested_len) {
*a = malloc(requested_len+4096);
if (len_of_source < requested_len) memcpy(*a, src, len_of_source);
else memcpy(*a, src, requested_len);
*dest = memmove((void *)round_up((uintptr_t)*a, 4096), *dest, requested_len);
return requested_len;
}
void __lseek_string__(char **src, int len, int offset) {
memmove(*src, *src+offset, len);
}
char * string1 = "hello";
char * string2;
char * s;
int main(void) {
read_fast_verify(string1, strlen(string1), &string2, &s, (strlen(string1) + 5));
__lseek_string__(&string2, strlen(string1), 5);
free(s);
}
输出
Starting program: /home/arch/universal-dynamic-loader/loader/test_case
called round_up
returning 0x55555555a000
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f2d3b0 in __memmove_ssse3_back () from /usr/lib/libc.so.6
但是,如果我像往常一样做
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdio.h>
uintptr_t round_up(uintptr_t value, uintptr_t size)
{
fprintf(stderr, "called round_up\nreturning %p\n", (void *) (value ? size * ((value + (size - 1)) / size) : size));
return value ? size * ((value + (size - 1)) / size) : size;
}
int read_fast_verify(const char *src, int len_of_source, char **dest, char ** a, int requested_len) {
*dest = malloc(requested_len+4096);
if (len_of_source < requested_len) memcpy(*dest, src, len_of_source);
else memcpy(*dest, src, requested_len);
*dest = memmove((void *)round_up((uintptr_t)*dest, 4096), *dest, requested_len);
return requested_len;
}
void __lseek_string__(char **src, int len, int offset) {
memmove(*src, *src+offset, len);
}
char * string1 = "hello";
char * string2;
char * s;
int main(void) {
read_fast_verify(string1, strlen(string1), &string2, &s, (strlen(string1) + 5));
__lseek_string__(&string2, strlen(string1), 5);
free(string2);
}
然后我明白了
called round_up
returning 0x564c86f54000
free(): invalid pointer
Aborted (core dumped)
并且来自 valgrind
==19175== HEAP SUMMARY:
==19175== in use at exit: 4,106 bytes in 1 blocks
==19175== total heap usage: 1 allocs, 1 frees, 4,106 bytes allocated
==19175==
==19175== Searching for pointers to 1 not-freed blocks
==19175== Checked 68,008 bytes
==19175==
==19175== 4,106 bytes in 1 blocks are possibly lost in loss record 1 of 1
==19175== at 0x4837757: malloc (vg_replace_malloc.c:299)
==19175== by 0x10923C: read_fast_verify (test_case.c:13)
==19175== by 0x109357: main (test_case.c:28)
==19175==
==19175== LEAK SUMMARY:
==19175== definitely lost: 0 bytes in 0 blocks
==19175== indirectly lost: 0 bytes in 0 blocks
==19175== possibly lost: 4,106 bytes in 1 blocks
==19175== still reachable: 0 bytes in 0 blocks
==19175== suppressed: 0 bytes in 0 blocks
==19175==
==19175== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==19175==
==19175== 1 errors in context 1 of 2:
==19175== Invalid free() / delete / delete[] / realloc()
==19175== at 0x4838904: free (vg_replace_malloc.c:530)
==19175== by 0x109388: main (test_case.c:30)
==19175== Address 0x4a30000 is 4,032 bytes inside a block of size 4,106 alloc'd
==19175== at 0x4837757: malloc (vg_replace_malloc.c:299)
==19175== by 0x10923C: read_fast_verify (test_case.c:13)
==19175== by 0x109357: main (test_case.c:28)
==19175==
==19175== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
因为我试图使其内存安全,因为我的动态链接器在读取一个根本不应该使用的.so(例如 libc 2.28)时使用了超过 2.7 GB(和超过 4 GB 的共享内存)。
解决方案
您应该存储先前的值并在移动成功完成后释放。现在你只是扔掉以前的地址。
也不确定您是否需要在此示例中移至此处,因为您将始终指向第一个指针内的相对地址并返回它,没有指向 free 的指针,而是原始指针。
推荐阅读
- nginx - NGINX 位置给出 404 错误,即使目录存在
- javascript - React - 身份验证的无效挂钩调用问题
- java - 检查文件是否存在并且在java中可读的最佳方法
- html - Codesandbox 预览在没有任何问题的情况下无法正常工作。我究竟做错了什么?
- http - Dart:http.dart 包中的 client.post() 方法挂起并且没有返回未来
- gradle - 从一台 PC 移动到另一台 PC 时颤动项目构建错误(从窗口到 mac)
- python - 用于百分比的 Python 格式字符串,在 % 之前有空格
- ios - 快速启用时在键盘上方显示按钮时出现问题
- c++ - 当“this”被 lambda 捕获时,是否必须显式使用它?
- angular - 如何“避免”孩子的变化在父母身上是可见的