4434 views|11 replies

7818

Posts

43

Resources
The OP

[Reliable Routine Alliance] Regarding the problem of malloc/realloc memory transfer between functions 20131216 [Copy link]

In the record of 20131206 (this record is in the QQ group forum, and since it is often not open, I just copy it here) In C, arrays, especially strings, are always very troublesome when dealing with various end characters and processing. Of course, C++ saves these, as long as you follow the advice of C++ primer and replace all C-style arrays with vector+string. Of course, C still needs to be used, and arrays still need to be used, so... let's write a set of tools similar to C++ string vector for it to use! ------------------------------------------------------------------------------------------------------------- So I thought about starting with a function to connect strings. Assuming that in C, we often need to complete many details including memory allocation by ourselves, but in the C++ string class, we don't need to consider so many things, we can just catch them directly, which is very cool. There are actually only two technical points involved here: 1. Dynamic memory allocation. Specifically, our goal is to pass only a pointer to the function without considering its space allocation. We only care about the effect of string operations; 2. Prevention of memory leaks. Because we intend to leave the memory allocation work in the function, therefore (of course, it was only when we actually encountered it during the later operation that we knew we needed to consider it) Therefore, in order to prevent memory leaks, we must consider how to release memory in different functions. At present, the problem of memory leaks has not been solved, but the connection has been completed. Sofa pastes the code after sorting it out.
This post is from Programming Basics

Latest reply

if(*dest == NULL) {strcpy(*dest,buff);return -1;} // Ensure that the original data can be recovered when allocation error occurs; I think there is something wrong with your answer. In the case of buff = *dest;, it is just equivalent to saving the pointer. So the meaning of strcpy(*dest,buff) is closer to *dest++= *dest++. It is the same as throwing the pointer back to *dest = buff. If buff=malloc (*dest), the whole data chain is saved. In addition, you said free(buff); is wrong? [ This post was last edited by 虚V界 on 2013-12-17 13:41]  Details Published on 2013-12-17 13:36

1077

Posts

3

Resources
2
Haha, fuck you.
This post is from Programming Basics

7818

Posts

43

Resources
3
  1. int StringCatch(char **dest,char *sub) { char *buff = NULL; if(dest == NULL || sub == NULL) return -1; buff = *dest; *dest = (char *)malloc(sizeof(char) * (strlen(buff) + strlen(sub) + 1) ); if(*dest == NULL) {strcpy(*dest,buff);return -1;} // When allocation error occurs, ensure that the original data can be recovered; strcpy(*dest,buff); strcat(*dest,sub); printf("=== in function\nwe get\n %s\n",*dest); // Output test information //free(buff); buff = NULL; return 0; }
复制代码
The basic idea of this function is to use a pointer inside the function to record the address of the original string; then reallocate memory for the string pointer *dest (from the calling function). If an error occurs, I can still retrieve the original data to ensure that the function's erroneous operation will not destroy the original data; secondly, once the operation is successful, because I deliberately do not release it before reallocation, I hope to release the original memory by releasing the address recorded by buff after the successful connection to avoid this part of the memory leak. But I found that this operation will report an error. I can't figure out why for the time being. Then I tried to do a very simple test. That is, passing a memory of the caller to the function and letting the function release it, it will also go wrong. So, this place is the key, the key is, It seems to imply to me: Can't release the memory from the caller in the function?
This post is from Programming Basics

7818

Posts

43

Resources
4
It's not enough to just support it. We have agreed to join the alliance, so we have to help. Help solve program problems, and I hope you can provide more useful, verified routines. Even if it's just a code snippet of more than ten lines, as long as it has been verified, it will be very useful!
This post is from Programming Basics

6376

Posts

17

Resources
5
I think this is reliable
This post is from Programming Basics

1077

Posts

3

Resources
6
en,hao,OK
This post is from Programming Basics

378

Posts

0

Resources
7
if(*dest == NULL) {strcpy(*dest,buff);return -1;} // Ensure that the original data can be recovered when allocation error occurs; I think there is something wrong with your answer. In the case of buff = *dest;, it is just equivalent to saving the pointer. So the meaning of strcpy(*dest,buff) is closer to *dest++= *dest++. It is the same as throwing the pointer back to *dest = buff. If buff=malloc (*dest), the whole data chain is saved. In addition, you said free(buff); is wrong? [ This post was last edited by 虚V界 on 2013-12-17 13:41]
This post is from Programming Basics

7818

Posts

43

Resources
8
First, let me explain the error in releasing the original memory. The book C and Pointers mentions the reason because the pointer (memory) passed to the free function can only be memory dynamically allocated by functions such as malloc, realloc and calloc, otherwise the program will terminate or terminate later. So this reminds me that I must change my thinking to change the memory. The same is true for realloc. The memory passed to it must be memory dynamically allocated by malloc and calloc;
This post is from Programming Basics

7818

Posts

43

Resources
9
I don't quite understand what you mean here. Do you mean that to retrieve the original memory block, we must use strcpy or assign values one by one? Instead of just passing the pointer? No, although I can't think of a way to simulate allocation failure or other ways to prove this conclusion. But from the principle analysis, I am sure that there is no problem. Because both addresses carry a valid memory block, and this memory block has not been released, so there is no problem in just passing the address carried by the pointer. Fine, I will show you a piece of code to verify and test it.
This post is from Programming Basics

7818

Posts

43

Resources
10
  1. void Test_TransBuffViaPoint(void) { char *buff = "Holding.\n"; char *pointerRecord = buff; printf("previous,we have buff with string\n %s\n",buff); buff = ( char *)malloc(100); //Already reallocated; if(buff == NULL) printf("allocate failed!"); else printf("now,we malloc the buff again,we get a new addr \n%p\n",buff); printf("for simulate the malloc failed case,\nI will set pointer to NULL.\n"); buff = NULL; if( buff == NULL) printf("now,buff had been set to NULL"); else printf("Jesus!This must be impossible to happen!\n"); printf("now,we pass the record back to buff"); buff = pointerRecord; printf("so...now let's see what we get from buff\n%s\n",buff); }
复制代码
Running result: [ This post was last posted by Xin Xin on 2013-12-18 02:24 Edited
This post is from Programming Basics

7818

Posts

43

Resources
11
Solution 20131218 As mentioned above, the trouble is that malloc/realloc/calloc and free functions can only operate dynamically allocated memory, that is, memory on the stack. Consider an important issue. Of course, we hope that this function can be used very widely, regardless of whether the memory passed by the user comes from a custom variable (on the stack) or even the memory in the constant area written casually in my routine. However, after repeated consideration, no better method was found. If you want to consider re-examining the operations of different memory areas such as the heap and stack yourself, it is too troublesome and may not be applicable to various models (single-chip microcomputers, PCs). Therefore, consider the second solution, imitating the string type of C++. Although C does not have classes, it can also be implemented through structure encapsulation and workarounds. In this way, the creation, destruction, and reallocation of memory are completely controlled within the implementation solution. In this way, you don’t have to worry about errors caused by freeing non-stack memory. In addition, I just retested it, and it is possible to dynamically allocate under IAR and STM8s. However, it may be related to the stack size setting. When I first tried to allocate 1000 bytes, an error occurred, but if I only allocated 100 bytes, no error occurred. [ This post was last edited by Xin Xin on 2013-12-18 18:39 ]
This post is from Programming Basics

7818

Posts

43

Resources
12

In fact, at that time, I just wanted to implement a C++-style string or vector

But this is actually very difficult, and I began to think about a question.

If I use C++ syntax when implementing it in a library, how can I make sure that it is better to use the most basic C++ part?

This post is from Programming Basics
Personal signature

强者为尊,弱者,死无葬身之地


Guess Your Favourite
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

    EEWorld
    subscription
    account

    EEWorld
    service
    account

    Automotive
    development
    circle

    Robot
    development
    community

    Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
    快速回复 返回顶部 Return list