简体   繁体   English

如何在记忆后释放分配的指针

[英]how to free a malloced pointer after a memmove

Solution

apparently, according to what is the difference between free(a) and memset(a, 0, malloced_size) (actual title is "Free function in c" but i feel that is not specific enough), i need to memset the data to 0 before/after i free it to actually free it as if it was never assigned any data 显然,根据free(a)和memset(a,0,malloced_size)之间的区别是什么 (实际标题是“ c中的Free function”,但我觉得不够具体),我需要将数据设置为0我释放它之前/之后实际上释放它,就好像它从未分配过任何数据一样

UPDATE: fixed 更新:固定

#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);
}

Problem 问题

How do I free a malloced pointer after I memmove it, as memmove seems to seg fault if I use a NULL dest as its return (eg char * dest = memmove(...);) 记忆后如何释放已分配的指针,因为如果我使用NULL dest作为返回值,则记忆似乎会出现段错误(例如char * dest = 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);
}

the output 输出

    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

However if I just do it as normal 但是,如果我照常做

#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);
}

then I get this 然后我得到这个

called round_up
returning 0x564c86f54000
free(): invalid pointer
Aborted (core dumped)

and from valgrind 和来自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)

as I am trying to make it memory safe as my dynamic linker is currently using over 2.7 gb (and over 4 GB shared memory) when reading a .so (such as libc 2.28) which it should not be at all. 因为我正在尝试使其内存安全,因为当读取.so(例如libc 2.28)时,我的动态链接器当前正在使用2.7 gb(和4 GB以上的共享内存),因此根本不应该使用它。

You should be storing the previous value and freeing after the move completed successfully. 您应该存储先前的值,并在移动成功完成后释放。 Right now you just throw away the previous address. 现在,您只需丢弃先前的地址即可。

Also not sure you need to move here in this example as you'll always point to a relative addrss within the first pointer and return that, there's no pointer to free but the origin pointer. 同样不确定在此示例中是否需要移动到此处,因为您将始终指向第一个指针内的相对地址并返回该地址,除了原始指针外,没有空闲指针。

See also Does memmove actually "move" a chunk of memory and leave behind zeros at the source? 另请参见memmove是否实际上“移动”了一块内存并在源头留下了零?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM