Here is my code:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
sResult = (TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #1
_tcscpy(sResult,(TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #2
Function:
TCHAR *GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames)
{
...
}
Which is correct to do? #1 or #2?
Thanks everyone.
Edit #1:
I'm using VS2008 in .cpp files, but really just C code.
I just need to open a file in GetValueFromFile and send the return string back. Should I be allocating memory in GVFF and freeing it in my program?
main()
{
TCHAR *sResult;
DWORD dwRetVal = GetValueFromFile(sFile,L"Dept",L"Name", &sResult);
...
free(sResult);sResult=NULL;
}
Like this?
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
{
dwL = GetStringDataLength(…)
*sValueData = (TCHAR *) calloc(dwL+1, sizeof(TCHAR));
_tcscpy_s(sValueData,dwL,sDataFromFile);
}
Well, first off, this is unnecessary in case 1 and leads to a problem:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
I don't know where 16384+1 is coming from, so I'll assume that's "correct" for now, but you proceed to set the pointer to another value in the very next line. That, my friend, is a memory leak. Why are you allocating memory that you don't need?
Your question really boils down to the implementation of GetValueFromFile. If that function returns a pointer (which it does) then it should certainly be a valid pointer and you are responsible for deallocating it (probably. Again, depends on the implementation).
There is no need to create a copy unless you actually need a copy. There is no "right" or "wrong" here from the information you have given us, we need to know the details of GetValueFromFile.
Per your edit:
That function does not return anything. At all. It's signature says it returns a DWORD, not a TCHAR*. It is obviously different than your first example as it initializes the pointer as an output argument (the 4th one), but that is not how you are calling it in your original example.
I am just further confused now, but if the function initializes the pointer then you need only declare (no memory allocation outside of the function) the pointer and pas in its address.
Given
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
Then the proper way to pass your pointer in is:
TCHAR *result;
GetValueFromFile(filename, dept, names, &result);
The function initializes your result variable to point to a valid location. Do not forget that you are now responsible for deallocating it!
1 clearly is not correct. You start by allocating space with calloc, but then you overwrite the point to that space with the return from GetValueFromFile. Assuming no intervening code that saves that pointer somewhere else, this means you no longer have access to the memory you allocated, so you can no longer access or free it. In short, a big memory leak.
Depending on how GetValueFromFile allocates the memory to which it returns a pointer, #2 might be just as bad, but the code you posted doesn't tell us enough to know. If it returns something like a pointer to a statically allocated buffer, then chances are it's correct (for some definition of correct). If it's allocating space with something like malloc or calloc, and expecting the client code to release that when needed, then it has a problem similar to that in #1.
Note that the "for some definition of correct" basically translates to something like: "wrong the minute you have more than one thread, or any need for reentrancy". Given the current ubiquity of multicore and multiprocessor systems, that definition is pretty narrow now, and getting narrower all the time.
Related
I am now studying C and in some code examples I saw that after we allocate some memory to a pointer, we have to check the pointer to be not a NULL. For example:
CVector *vector = malloc(sizeof(struct CVectorImplementation));
assert(vector != NULL);
another example:
vector->elements = realloc(vector->elements, vector->elemsz * vector->vec_capacity);
assert(vector->elements != NULL);
However, I think since the pointer is already been allocated, then it has the address of the allocated memory as its value, thus is it always necessary? why?
If you've reassigned the original pointer in response to realloc, it's too late to do anything useful in response to a failure. When realloc fails, it returns NULL, but it does not free the original pointer. So even if you have some reasonable response to an allocation failure (not common), you've already leaked the memory you were trying to realloc.
The answer to your main question is mostly "it's a bad idea to allow NULL pointer dereferences to occur because it's a source of vulnerabilities"; usually the vulnerabilities crop up in kernel code (where NULL is just as valid an address as anywhere else), but even when it's not exploitable, it means the program segfaults instead of reporting an error in a useful way.
It's a great idea to check the pointer returned from malloc/realloc.
If there's an error, you will get a null value returned. Use this check to your advantage because if you make reference to the same pointer later in your program and your program suddenly crashes, then chances are the pointer is set to null.
If you do have a valid pointer from a malloc/realloc call, then make sure you use it inside the free() function before deciding to modify the pointer value and before the program terminates, otherwise, you may run into memory leaks.
If you need to change the pointer value to write to a different section of the memory you allocated, then use another pointer.
Here's code in C that shows what I mean:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *block=calloc(1,10000);
if (block==NULL){
printf("Can't allocate memory\n");
return -1;
}
memset(block,48,20); //set 1st 20 bytes of memory to number zero (ascii code 48)
char *insideoftheblock=block+10; // I set a pointer to go to index #10 in the memory
*insideoftheblock='x';
*insideoftheblock++;
*insideoftheblock='y';
printf("Memory = '%s'",block);
free(block);
}
P.S.
I updated my code to include a check to see if memory has been actually allocated.
The realloc function attempts to allocate new memory. If this allocation fails then the realloc function returns NULL. Your code must deal with this situation.
If you want to abort your program in this case then the assert as you currently have it is suitable. If you want to recover, then you will need to store the realloc result in a separate variable while you assess the situation, e.g.:
void *new = realloc(vector->elements, vector->elemsz * vector->vec_capacity);
if ( !new )
// take some action.... the old vector->elements is still valid
else
vector->elements = new;
A failed allocation typical results in 1 of 2 actions:
1) Exit the program with a diagnostic. This is far better than not checking and letting the code continue to who--knows--what.
2) In select circumstances, code can cope with the failure. Maybe freeing other resources and trying again, return a failure code and leave the problem to the calling routine or writing a "suicide note" and re-starting the system. IAC, the action is very specific to the situation.
Robust code checks the result. Beginner code does not.
I am pretty new to C programming and I have several functions returning type char *
Say I declare char a[some_int];, and I fill it later on. When I attempt to return it at the end of the function, it will only return the char at the first index. One thing I noticed, however, is that it will return the entirety of a if I call any sort of function on it prior to returning it. For example, my function to check the size of a string (calling something along the lines of strLength(a);).
I'm very curious what the situation is with this exactly. Again, I'm new to C programming (as you probably can tell).
EDIT: Additionally, if you have any advice concerning the best method of returning this, please let me know. Thanks!
EDIT 2: For example:
I have char ret[my_strlen(a) + my_strlen(b)]; in which a and b are strings and my_strlen returns their length.
Then I loop through filling ret using ret[i] = a[i]; and incrementing.
When I call my function that prints an input string (as a test), it prints out how I want it, but when I do
return ret;
or even
char *ptr = ret;
return ptr;
it never supplies me with the full string, just the first char.
A way not working to return a chunk of char data is to return it in memory temporaryly allocated on the stack during the execution of your function and (most probably) already used for another purpose after it returned.
A working alternative would be to allocate the chunk of memory ont the heap. Make sure you read up about and understand the difference between stack and heap memory! The malloc() family of functions is your friend if you choose to return your data in a chunk of memory allocated on the heap (see man malloc).
char* a = (char*) malloc(some_int * sizeof(char)) should help in your case. Make sure you don't forget to free up memory once you don't need it any more.
char* ret = (char*) malloc((my_strlen(a) + my_strlen(b)) * sizeof(char)) for the second example given. Again don't forget to free once the memory isn't used any more.
As MByD correctly pointed out, it is not forbidden in general to use memory allocated on the stack to pass chunks of data in and out of functions. As long as the chunk is not allocated on the stack of the function returning this is also quite well.
In the scenario below function b will work on a chunk of memory allocated on the stackframe created, when function a entered and living until a returns. So everything will be pretty fine even though no memory allocated on the heap is involved.
void b(char input[]){
/* do something useful here */
}
void a(){
char buf[BUFFER_SIZE];
b(buf)
/* use data filled in by b here */
}
As still another option you may choose to leave memory allocation on the heap to the compiler, using a global variable. I'd count at least this option to the last resort category, as not handled properly, global variables are the main culprits in raising problems with reentrancy and multithreaded applications.
Happy hacking and good luck on your learning C mission.
Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)
I'm trying to write a simple C program on Ubuntu using Eclipse CDT (yes, I'm more comfortable with an IDE and I'm used to Eclipse from Java development), and I'm stuck with something weird. On one part of my code, I initialize a char array in a function, and it is by default pointing to the same location with one of the inputs, which has nothing to do with that char array. Here is my code:
char* subdir(const char input[], const char dir[]){
[*] int totallen = strlen(input) + strlen(dir) + 2;
char retval[totallen];
strcpy(retval, input);
strcat(retval, dir);
...}
Ok at the part I've marked with [*], there is a checkpoint. Even at that breakpoint, when I check y locals, I see that retval is pointing to the same address with my argument input. It not even possible as input comes from another function and retval is created in this function. Is is me being unexperienced with C and missing something, or is there a bug somewhere with the C compiler?
It seems so obvious to me that they should't point to the same (and a valid, of course, they aren't NULL) location. When the code goes on, it literally messes up everything; I get random characters and shapes in console and the program crashes.
I don't think it makes sense to check the address of retval BEFORE it appears, it being a VLA and all (by definition the compiler and the debugger don't know much about it, it's generated at runtime on the stack).
Try checking its address after its point of definition.
EDIT
I just read the "I get random characters and shapes in console". It's obvious now that you are returning the VLA and expecting things to work.
A VLA is only valid inside the block where it was defined. Using it outside is undefined behavior and thus very dangerous. Even if the size were constant, it still wouldn't be valid to return it from the function. In this case you most definitely want to malloc the memory.
What cnicutar said.
I hate people who do this, so I hate me ... but ... Arrays of non-const size are a C99 extension and not supported by C++. Of course GCC has extensions to make it happen.
Under the covers you are essentially doing an _alloca, so your odds of blowing out the stack are proportional to who has access to abuse the function.
Finally, I hope it doesn't actually get returned, because that would be returning a pointer to a stack allocated array, which would be your real problem since that array is gone as of the point of return.
In C++ you would typically use a string class.
In C you would either pass a pointer and length in as parameters, or a pointer to a pointer (or return a pointer) and specify the calls should call free() on it when done. These solutions all suck because they are error prone to leaks or truncation or overflow. :/
Well, your fundamental problem is that you are returning a pointer to the stack allocated VLA. You can't do that. Pointers to local variables are only valid inside the scope of the function that declares them. Your code results in Undefined Behaviour.
At least I am assuming that somewhere in the ..... in the real code is the line return retval.
You'll need to use heap allocation, or pass a suitably sized buffer to the function.
As well as that, you only need +1 rather than +2 in the length calculation - there is only one null-terminator.
Try changing retval to a character pointer and allocating your buffer using malloc().
Pass the two string arguments as, char * or const char *
Rather than returning char *, you should just pass another parameter with a string pointer that you already malloc'd space for.
Return bool or int describing what happened in the function, and use the parameter you passed to store the result.
Lastly don't forget to free the memory since you're having to malloc space for the string on the heap...
//retstr is not a const like the other two
bool subdir(const char *input, const char *dir,char *retstr){
strcpy(retstr, input);
strcat(retstr, dir);
return 1;
}
int main()
{
char h[]="Hello ";
char w[]="World!";
char *greet=(char*)malloc(strlen(h)+strlen(w)+1); //Size of the result plus room for the terminator!
subdir(h,w,greet);
printf("%s",greet);
return 1;
}
This will print: "Hello World!" added together by your function.
Also when you're creating a string on the fly you must malloc. The compiler doesn't know how long the two other strings are going to be, thus using char greet[totallen]; shouldn't work.
I am working with my first straight C project, and it has been a while since I worked on C++ for that matter. So the whole memory management is a bit fuzzy.
I have a function that I created that will validate some input. In the simple sample below, it just ignores spaces:
int validate_input(const char *input_line, char** out_value){
int ret_val = 0; /*false*/
int length = strlen(input_line);
out_value =(char*) malloc(sizeof(char) * length + 1);
if (0 != length){
int number_found = 0;
for (int x = 0; x < length; x++){
if (input_line[x] != ' '){ /*ignore space*/
/*get the character*/
out_value[number_found] = input_line[x];
number_found++; /*increment counter*/
}
}
out_value[number_found + 1] = '\0';
ret_val = 1;
}
return ret_val;
}
Instead of allocating memory inside the function for out_value, should I do it before I call the function and always expect the caller to allocate memory before passing into the function? As a rule of thumb, should any memory allocated inside of a function be always freed before the function returns?
I follow two very simple rules which make my life easier.
1/ Allocate memory when you need it, as soon as you know what you need. This will allow you to capture out-of-memory errors before doing too much work.
2/ Every allocated block of memory has a responsibility property. It should be clear when responsibility passes through function interfaces, at which point responsibility for freeing that memory passes with the memory. This will guarantee that someone has a clearly specified requirement to free that memory.
In your particular case, you need to pass in a double char pointer if you want the value given back to the caller:
int validate_input (const char *input_line, char **out_value_ptr) {
: :
*out_value_ptr =(char*) malloc(length + 1); // sizeof(char) is always 1
: :
(*out_value_ptr)[number_found] = input_line[x];
: :
As long as you clearly state what's expected by the function, you could either allocate the memory in the caller or the function itself. I would prefer outside of the function since you know the size required.
But keep in mind you can allow for both options. In other words, if the function is passed a char** that points to NULL, have it allocate the memory. Otherwise it can assume the caller has done so:
if (*out_value_ptr == NULL)
*out_value_ptr =(char*) malloc(length + 1);
You should free that memory before the function returns in your above example. As a rule of thumb you free/delete allocated memory before the scope that the variable was defined in ends. In your case the scope is your function so you need to free it before your function ends. Failure to do this will result in leaked memory.
As for your other question I think it should be allocated going in to the function since we want to be able to use it outside of the function. You allocate some memory, you call your function, and then you free your memory. If you try and mix it up where allocation is done in the function, and freeing is done outside it gets confusing.
The idea of whether the function/module/object that allocates memory should free it is somewhat of a design decision. In your example, I (personal opinion here) think it is valid for the function to allocate it and leave it up to the caller to free. It makes it more usable.
If you do this, you need to declare the output parameter differently (either as a reference in C++ style or as char** in C style. As defined, the pointer will exist only locally and will be leaked.
A typical practice is to allocate memory outside for out_value and pass in the length of the block in octets to the function with the pointer. This allows the user to decide how they want to allocate that memory.
One example of this pattern is the recv function used in sockets:
ssize_t recv(int socket, void *buffer, size_t length, int flags);
Here are some guidelines for allocating memory:
Allocate only if necessary.
Huge objects should be dynamically
allocated. Most implementations
don't have enough local storage
(stack, global / program memory).
Set up ownership rules for the
allocated object. Owner should be
responsible for deleting.
Guidelines for deallocating memory:
Delete if allocated, don't delete
objects or variables that were not
dynamically allocated.
Delete when not in use any more.
See your object ownership rules.
Delete before program exits.
In this example you should be neither freeing or allocating memory for out_value. It is typed as a char*. Hence you cannot "return" the new memory to the caller of the function. In order to do that you need to take in a char**
In this particular scenario the buffer length is unknown before the caller makes the call. Additionally making the same call twice will produce different values since you are processing user input. So you can't take the approach of call once get the length and call the second time with the allocated buffer. Hence the best approach is for the function to allocate the memory and pass the responsibility of freeing onto the caller.
First, this code example you give is not ANSI C. It looks more like C++. There is not "<<" operator in C that works as an output stream to something called "cout."
The next issue is that if you do not free() within this function, you will leak memory. You passed in a char * but once you assign that value to the return value of malloc() (avoid casting the return value of malloc() in the C programming language) the variable no longer points to whatever memory address you passed in to the function. If you want to achieve that functionality, pass a pointer to a char pointer char **, you can think of this as passing the pointer by reference in C++ (if you want to use that sort of language in C, which I wouldn't).
Next, as to whether you should allocate/free before or after a function call depends on the role of the function. You might have a function whose job it is to allocate and initialize some data and then return it to the caller, in which case it should malloc() and the caller should free(). However, if you are just doing some processing with a couple of buffers like, you may tend to prefer the caller to allocate and deallocate. But for your case, since your "validate_input" function looks to be doing nothing more than copying a string without the space, you could just malloc() in the function and leave it to the caller. Although, since in this function, you simply allocate the same size as the whole input string, it almost seems as if you might as well have the caller to all of it. It all really depends on your usage.
Just make sure you do not lose pointers as you are doing in this example
Some rough guidelines to consider:
Prefer letting the caller allocate the memory. This lets it control how/where that memory is allocated. Calling malloc() directly in your code means your function is dictating a memory policy.
If there's no way to tell how much memory may be needed in advance, your function may need to handle the allocation.
In cases where your function does need to allocate, consider letting the caller pass in an allocator callback that it uses instead of calling malloc directly. This lets your function allocate when it needs and as much as it needs, but lets the caller control how and where that memory is allocated.