Need dynamically allocated (initialized) static variable - c

I need a static string(equivalent) variable in C and I'm having troubles implementing something like that.
I need to add content to that string every time the function is called. I tried with
static char *result = (char*)calloc(0, sizeof(char));
But that way I got:
error: initializer element is not
constant
Which makes sense, but I really don't know how to do this differently (tried with global variable also, but no success).
Anyone can help?

static initializers must be constant, as your error message indicates.
Assign it NULL, then in some other function, test if it's NULL, allocate the resources it needs (some sensible default) and go from there. Ensure you do clean up after you're done, and if this is a threaded environment, I suggest you go a different route put this in other storage that you pass along wherever you need it.

If you need to increase array length, use realloc instead.
char *buf = NULL;
while(/* some loop here */){
buf = realloc(buf, sizeof(/* new content */));
... // copy your new content to buf here
}
If you only add content, maybe better to use lists instead?

The most common way I've seen of doing this is to initialize a pointer to NULL, and store a length- optionally an end pointer is stored as well. When the function is called, check to see if you have enough space in your buffer available, and if not then realloc the memory chunk. Usually you don't want to realloc every time, and instead grow by either some fixed amount (usually selected based on the memory alignment of the system), or else to double the previous size (be sure to make sure you actually have enough free space!).
#define MYDATA_GROW_AMOUNT (12345) //exploit memory alignment on your system
...
/* if the compiler supports it, consider using __thread__ here */
static /* __thread__ */ char *mydata = NULL;
static /* __thread__ */ char *mydata_end = NULL;
static /* __thread__ */ size_t mydata_len = 0;
...
/* gcc? you might want to use
if(__builtin_expect((mydata_len < required_data_len),0))
here instead */
if(mydata_len < required_data_len)
{
mydata_end = mydata + mydata_len;
mydata_len += MYDATA_GROW_AMOUNT;
mydata = realloc(mydata,mydata_len);
}
...

I was able to get this to work for a "fixed" size array, i.e. the length can be defined during run-time, NOT compile time. I created a function which has the empty pointer itself A as an input, then alters it within and also returns it. The length len is custom run-time length:
char *malloc_char_array(char* &A, int len);
Then call that function in the array initialization:
static char *result = malloc_char_array(result, 50); //test length of 50
The static initialization only occurs the very first time the function is called, so it works great for arrays that need to be dynamic in size (i.e. not defined during compile time), yet still remain fixed throughout the entire run of the program.
And the allocating function would look something like:
char *malloc_char_array(char* &A, int len)
{
A = (char*) malloc(len * sizeof(char));
return A;
}
With this method there's no need to free the "static" allocated memory, just let it stay in the stack until the program quits.

Related

How to initialize array size in a library in C?

I'm creating a C-library with .h and .c files for a ring buffer. Ideally, you would initialize this ring buffer library in the main project with something like ringbuff_init(int buff_size); and the size that is sent, will be the size of the buffer. How can I do this when arrays in C needs to be initialized statically?
I have tried some dynamically allocating of arrays already, I did not get it to work. Surely this task is possible somehow?
What I would like to do is something like this:
int buffSize[];
int main(void)
{
ringbuffer_init(100); // initialize buffer size to 100
}
void ringbuffer_init(int buff_size)
{
buffSize[buff_size];
}
This obviously doesn't compile because the array should have been initialized at the declaration. So my question is really, when you make a library for something like a buffer, how can you initialize it in the main program (so that in the .h/.c files of the buffer library) the buffer size is set to the wanted size?
You want to use dynamic memory allocation. A direct translation of your initial attempt would look like this:
size_t buffSize;
int * buffer;
int main(void)
{
ringbuffer_init(100); // initialize buffer size to 100
}
void ringbuffer_init(size_t buff_size)
{
buffSize = buff_size;
buffer = malloc(buff_size * sizeof(int));
}
This solution here is however extremely bad. Let me list the problems here:
There is no check of the result of malloc. It could return NULL if the allocation fails.
Buffer size needs to be stored along with the buffer, otherwise there's no way to know its size from your library code. It isn't exactly clean to keep these global variables around.
Speaking of which, these global variables are absolutely not thread-safe. If several threads call functions of your library, results are inpredictible. You might want to store your buffer and its size in a struct that would be returned from your init function.
Nothing keeps you from calling the init function several times in a row, meaning that the buffer pointer will be overwritten each time, causing memory leaks.
Allocated memory must be eventually freed using the free function.
In conclusion, you need to think very carefully about the API you expose in your library, and the implementation while not extremely complicated, will not be trivial.
Something more correct would look like:
typedef struct {
size_t buffSize;
int * buffer;
} RingBuffer;
int ringbuffer_init(size_t buff_size, RingBuffer * buf)
{
if (buf == NULL)
return 0;
buf.buffSize = buff_size;
buf.buffer = malloc(buff_size * sizeof(int));
return buf.buffer != NULL;
}
void ringbuffer_free(RingBuffer * buf)
{
free(buf.buffer);
}
int main(void)
{
RingBuffer buf;
int ok = ringbuffer_init(100, &buf); // initialize buffer size to 100
// ...
ringbuffer_free(&buf);
}
Even this is not without problems, as there is still a potential memory leak if the init function is called several times for the same buffer, and the client of your library must not forget to call the free function.
Static/global arrays can't have dynamic sizes.
If you must have a global dynamic array, declare a global pointer instead and initialize it with a malloc/calloc/realloc call.
You might want to also store its size in an accompanying integer variable as sizeof applied to a pointer won't give you the size of the block the pointer might be pointing to.
int *buffer;
int buffer_nelems;
char *ringbuffer_init(int buff_size)
{
assert(buff_size > 0);
if ( (buffer = malloc(buff_size*sizeof(*buffer)) ) )
buffer_nelems = buff_size;
return buffer;
}
You should use malloc function for a dynamic memory allocation.
It is used to dynamically allocate a single large block of memory with the specified size. It returns a pointer of type void which can be cast into a pointer of any form.
Example:
// Dynamically allocate memory using malloc()
buffSize= (int*)malloc(n * sizeof(int));
// Initialize the elements of the array
for (i = 0; i < n; ++i) {
buffSize[i] = i + 1;
}
// Print the elements of the array
for (i = 0; i < n; ++i) {
printf("%d, ", buffSize[i]);
}
I know I'm three years late to the party, but I feel I have an acceptable solution without using dynamic allocation.
If you need to do this without dynamic allocation for whatever reason (I have a similar issue in an embedded environment, and would like to avoid it).
You can do the following:
Library:
int * buffSize;
int buffSizeLength;
void ringbuffer_init(int buff_size, int * bufferAddress)
{
buffSize = bufferAddress;
buffSizeLength = buff_size;
}
Main :
#define BUFFER_SIZE 100
int LibraryBuffer[BUFFER_SIZE];
int main(void)
{
ringbuffer_init(BUFFER_SIZE, LibraryBuffer ) // initialize buffer size to 100
}
I have been using this trick for a while now, and it's greatly simplified some parts of working with a library.
One drawback: you can technically mess with the variable in your own code, breaking the library. I don't have a solution to that yet. If anyone has a solution to that I would love to here it. Basically good discipline is required for now.
You can also combine this with #SirDarius 's typedef for ring buffer above. I would in fact recommend it.

Return string from function that will be used to create a DLL

I need to create a DLL file that can be used for MS Access and other applications that will return a string when fed parameters. I am fairly familiar with MS Access but an absolute novice at C.
Following is the code I am experimenting with. I want to be able to issue a call like getstring(32.1, 123.2, "here", 25) and have it return a string of up to 60 characters in length. The actual code works fine and buf contains the string I want when it's finished running but I am having trouble handing it back to the calling function.
UPDATE:
Ok, I've worked out how to create a DLL and run a function from VBA but I am still struggling to understand how to return strings. I think if I can get this to work, I can work out my whole project. By running the following code I can get VBA to return the square of the input number e.g. feed it a parameter of 10 and I get an answer of 100
double _stdcall square(double *x)
{
return *x * *x;
}
However when I run the following code in Excel and feed it a parameter of "test" all I get back is a square box character.
char _stdcall Boxx(char *x)
{
return *x;
}
In this case all I want it to return is what I entered. If I can get it to return that I hope to be able to replace that with the actual result. Any suggestions?
char * Getstring(double lat, double lon, char *name, double zoom)
{
char buf[60] = { '\0' }; // Set the max length of the final link string
int ret = GenShortDroidMapUrl(lat, lon, zoom, name, buf, sizeof(buf) - 1);
return buf;
}
In the posted code, buf[] is an automatic variable whose lifetime ends after the Getstring() function has returned. Since buf[] will no longer exist when control of the program has returned to the caller, a pointer to this variable will be invalid after Getstring() has returned.
One solution is to pass an additional argument into the Getstring() function to accept the string, along with a size argument. Since buf will decay to a pointer in the function call, the sizeof operator can't be used in Getstring() to find the size of the array, but buf_sz holds this value:
char * Getstring(char *buf, size_t buf_sz, double lat, double lon, char *name, double zoom)
{
// buf[] has been zero-initialized in the caller
int ret = GenShortDroidMapUrl(lat, lon, zoom, name, buf, buf_sz - 1);
return buf;
}
Another option that does not require changing the function signature is to dynamically allocate storage for the returned string. Again, buf is a pointer to char in Getstring(), so the sizeof expression in GenShortDroidMapUrl() will need to be replaced; this time the constant BUF_SZ has been used here. Note that the malloced memory will need to be freed by the caller later.
#include <string.h>
#define BUF_SZ 60
/* ... */
char * Getstring(double lat, double lon, char *name, double zoom)
{
char *buf = malloc(sizeof *buf * BUF_SZ);
memset(buf, '\0', BUF_SZ);
/* Or use calloc() and avoid the call to memset() */
// char *buf = calloc(BUF_SZ, sizeof *buf);
int ret = GenShortDroidMapUrl(lat, lon, zoom, name, buf, BUF_SZ - 1);
return buf;
}
If Getstring() is part of a library, you need to ensure that the deallocator function matches the allocation functions. That is, there may be problems if the version of malloc() or calloc() that Getstring() is linked against differs from the version of free() that the calling code is linked against. One solution is to provide a deallocation function with the library. This could be as simple as wrapping free() in another function to be used by the caller to ensure that a matching deallocator is used. Here, the function DLL_Free() is part of the DLL, and malloc(), calloc(), and free() would all be linked against the same library when the DLL is created. The caller that uses Getstring() would use DLL_Free() to deallocate. From the caller, free() may not work as expected to deallocate the memory allocated by Getstring(), but DLL_Free() would since this deallocator uses the version of free() that matches the allocators used in the DLL.
/* Deallocation function included in DLL that matches allocation
* functions used in library
*/
void DLL_Free(void *ptr)
{
free(ptr);
}
There are many ways to return a string, but respect the lifetime of buffers:
Can a local variable's memory be accessed outside its scope?
One is to let the caller supply the buffer. Return how much space would have been needed, and a simple comparison will tell you whether it was enough.
Another is to use a static, optionally thread-local, buffer. Beware the restrictions on concurrency and reentrancy.
And finally, you can allocate it dynamically. Remember that it has to be freed with the same system, which on windows often means you have to manually export the way to free it from your DLL. Better not to reinvent the wheel, look at BSTRs for example.
You could either declare buf static and let the function return const char *. But that would not be reentrant. So another solution is to return strdup(buf), which will return a copy that the caller needs to free after use (otherwise you will have a memory leak).

Error trying to change contents of string pointer in C

I'm working on a program in C and one of my key functions is defined as follows:
void changeIndex(char* current_index)
{
char temp_index[41]; // note: same size as current_index
// do stuff with temp_index (inserting characters and such)
current_index = temp_index;
}
However, this function has no effect on current_index. I thought I found a fix and tried changing the last line to
strcpy(current_index, temp_index)
but this gave me yet another error. Can anyone spot what I'm doing wrong here? I basically just want to set the contents of current_index equal to that of temp_index at each call of changeIndex.
If more information is needed, please let me know.
strcpy should work if current_index points to allocated memory of sufficient size. Consider the following example, where changeIndex require additional parameter - size of distination string:
void changeIndex(char* current_index, int max_length)
{
// check the destination memory
if(current_index == NULL)
{
return; // do nothing
}
char temp_index[41];
// do stuff with temp_index (inserting characters and such)
// copy to external memory, that should be allocated
strncpy(current_index, temp_index, max_length-1);
current_index[max_length-1] = '\0';
}
Note: strncpy is better for the case when temp_index is longer then current_index.
Examples of usage:
// example with automatic memory
char str[20];
changeIndex(str, 20);
// example with dinamic memory
char * ptr = (char *) malloc(50);
changeIndex(ptr, 50);
Obviously defining a local char array on the stack and returning a pointer to it is wrong. You should never do that as the memory is not defined after the function ends.
In addition to the previous answers: The strncpy char pointer (which seems unsafe for my opinion), and the malloc which is safer but you need to remember to free it outside of the function (and its inconsistent with the hierarchy of the program) you can do the following:
char* changeIndex()
{
static char temp_index[41]; // note: same size as current_index
// do stuff with temp_index (inserting characters and such)
return temp_index;
}
As the char array is static it will not be undefined at the end of the function and you do not need to remember to free the pointer at the end of the use.
Caveat: If you are using multiple thread you cannot use this option as the static memory could be changed by different threads entering the function at the same time
Your array temp_index is local for function, then *current_index don't take what u want.
U can use also function strdup . Function return begin memory location of copied string , or NULL if error occurred, lets say ( char *strdup(char *) )
char temp[] = "fruit";
char *line = strdup(temp );

Pointers and assignment in a sub-function

I have a small program that creates a semver struct with some variables in it:
typedef struct {
unsigned major;
unsigned minor;
unsigned patch;
char * note;
char * tag;
} semver;
Then, I would like to create a function which creates a semver struct and returns it to the caller. Basically, a Factory.
That factory would call an initialize function to set the default values of the semver struct:
void init_semver(semver * s) {
s->major = 0;
s->minor = 0;
s->patch = 0;
s->note = "alpha";
generate_semver(s->tag, s);
}
And on top of that, I would like a function to generate a string of the complete semver tag.
void generate_semver(char * tag, semver * s) {
sprintf( tag, "v%d.%d.%d-%s",
s->major, s->minor, s->patch, s->note);
}
My problem appears to lie in this function. I have tried returning a string, but have heard that mallocing some space is bad unless you explicitly free it later ;) In order to avoid this problem, I decided to try to pass a string to the function to have it be changed within the function with no return value. I'm trying to loosely follow something like DI practices, even though I'd really like to separate the concerns of these functions and have the generate_semver function return a string that I can use like so:
char * generate_semver(semver * s) {
char * full_semver;
sprintf( full_semver, "v%d.%d.%d-%s",
s->major, s->minor, s->patch, s->note);
return full_semver; // I know this won't work because it is defined in the local stack and not outside.
}
semver->tag = generate_semver(semver);
How can I do this?
My problem appears to lie in this function. I have tried returning a string, but have heard that mallocing some space is bad unless you explicitly free it later.
Explicitly freeing dynamically allocated memory is required to avoid memory leaks. However, it is not necessarily a task that the end users need to perform directly: an API often provides a function to deal with this.
In your case, you should provide a deinit_semver function that does the clean up of memory that init_semver has allocated dynamically. These two functions behave in a way that is similar to constructor and destructor; init_semver is not a factory function, because it expects the semver struct to be allocated, rather than allocating it internally.
Here is one way of doing it:
void init_semver(semver * s, int major, int minor, int pathc, const char * note) {
s->major = major;
s->minor = minor;
s->patch = pathc;
size_t len = strlen(note);
s->note = malloc(len+1);
strcpy(s->note, note);
s->tag = malloc(40 + len);
sprintf(s->tag, "v%d.%d.%d-%s", major, minor, patch, note);
}
void deinit_semver(semver *s) {
free(s->note);
free(s->tag);
}
Note the changes above: rather than using fixed values for the components of struct semver, this code takes the values as parameters. In addition, the code copies the note into a dynamically allocated buffer, rather than pointing to it directly.
The deinit function does the clean-up by free-ing both fields that were allocated dynamically.
A char * on its own is just a pointer to memory. To accomplish what you want you will either need to instead use a fixed size field, i.e. char[33], or you can dynamically allocate the memory as needed.
As it is, your generate_semver function is attempting to print to an unknown address. Let's look at one solution.
typedef struct {
unsigned major;
unsigned minor;
unsigned patch;
char note[32];
char tag[32];
} semver;
Now, in your init_semver function, the line previously s->note = "alpha"; will become a string copy, as arrays are not a valid lvalue.
strncpy(s->note, "alpha", 31);
s->note[31] = '\0';
strncpy will copy a string from the second parameter to the first up to the number of bytes in the third parameter. The second line ensures that a trailing null terminator is in place.
Similarly, in the generate_semver function, it would directly work in the buffer:
void generate_semver(semver * s) {
snprintf( s->tag, 32, "v%d.%d.%d-%s",
s->major, s->minor, s->patch, s->note);
}
This will directly print to the array in the structure, with a maximum character limit. snprintf does append a trailing null terminator (unlike strncpy), so we don't need to worry about adding it ourselves.
You mention having to free allocated memory, and then say: "In order to avoid this problem". Well, it's not so much a problem, but rather a necessity of the C language. It's common to have functions that allocate memory, and require the caller to free it again.
The idiomatic way is to have a pair of "create" and "destroy" functions. So I'd suggest doing it like this:
// Your factory function
semver* create_semver() {
semver* instance = malloc(sizeof(*instance));
init_semver(instance); // will also allocate instance->tag and ->note
return instance;
}
// Your destruction function
void free_semver(semver* s) {
free(semver->tag);
free(semver->note);
free(semver);
}

Returning populated string array from function C

It's the first time posting so I apologise for any confusion:
I am writing a function like this:
int myFunc(char* inputStr, int *argCTemp, char** argVTemp[]);
The purpose of my function is to take a copy of the input string (basically any user input) and then use strtok to convert it to tokens and populate an array via an array pointer (argV). When myFunc is finished, hopefully I have the argument count and array of strings from my inputStr string.
Here is an example of how I call it:
int main(int argc, char** argv[])
{
int argCTemp = -1;
char** argVTemp;
// 1 Do Stuff
// 2 Get input string from user
// 3 then call myfunc like this:
myFunc(inputStr, &argCTemp, &argVTemp);
// 4: I get garbage whenever I try to use "argVTemp[i]"
}
My Questions: How should I best do this in a safe and consistent way. How do the pro's do this?
I don't use malloc because:
I don't know the number of arguments or the length of each for my input (to dynamically allocate the space). I figured that's why I use pointers
since I declare it in the main function, I thought the pointers to/memory used by argCTemp and argVTemp would be fine/remain in scope even if they are on the stack.
I know when myFunc exits it invalidates any stack references it created, so that's why I sent it pointers from a calling function. Should I be using pointers and malloc and such or what?
Last thing: before myfunc exits, I check to see the values of argCTemp and argVTemp and they have valid content. I am setting argCtemp and argVtemp like this:
(*argCTemp) = argCount;
(*argVTemp)[0] = "foo";
and it seems to be working just fine BEFORE the function exits. Since I'm setting pointers somewhere else in memory, I'm confused why the reference is failing. I tried using malloc INSIDE myFunc when setting the pointers and it is still becoming garbage when myFunc ends and is read by the calling function.
I'm sorry if any of this is confusing and thank you in advance for any help.
Since "don't know the number of arguments or the length of each for my input ", you can use malloc also. When your buffer abouting full, you should realloc your buffer.
The better way: You needn't store whole input. A line, a token or a block is better. Just set a static array to store them. and maybe hash is better if your input more than 100 mb.
I'm sorry for my poor English.
You send an uninitialized pointer (you call is isn't correct as well, you don't need the & ) to the function, this pointer points to some random place and that is why you get garbage, you can also get segmentation fault.
You can do one of the two.
Per allocate a large enough array which can be static for example
static char * arr[MAX SIZE] and send it (char **)&arr in the function call, or run twice and use malloc.
You should also pass the max size, or use constant and make sure you don't pass it.
Lets say you the number of tokens in int n then
char * arr[] = malloc(sizeof(int *)*n);
this will create array of pointers, now you pass it to your populate function by calling
it with (char **)&arr, and use it like you did in your code
for example (*argVTemp)[0] = ;.
(when the array is not needed any more don't forget to free it by caliing free(arr))
Generally speaking, since you don't know how many tokens will be in the result you'll need to allocate the array dynamically using malloc(), realloc() and/or some equivalent. Alternatively you can have the caller pass in array along with the array's size and return an error indication if the array isn't large enough (I do this for simple command parsers on embedded systems where dynamic allocation isn't appropriate).
Here's an example that allocates the returned array in small increments:
static
char** myFunc_realloc( char** arr, size_t* elements)
{
enum {
allocation_chunk = 16
};
*elements += allocation_chunk;
char** tmp = (char**) realloc( arr, (*elements) * sizeof(char*));
if (!tmp) {
abort(); // or whatever error handling
}
return tmp;
}
void myFunc_free( char** argv)
{
free(argv);
}
int myFunc(char* inputStr, int *argCTemp, char** argVTemp[])
{
size_t argv_elements = 0;
size_t argv_used = 0;
char** argv_arr = NULL;
char* token = strtok( inputStr, " ");
while (token) {
if ((argv_used+1) >= argv_elements) {
// we need to realloc - the +1 is because we want an extra
// element for the NULL sentinel
argv_arr = myFunc_realloc( argv_arr, &argv_elements);
}
argv_arr[argv_used] = token;
++argv_used;
token = strtok( NULL, " ");
}
if ((argv_used+1) >= argv_elements) {
argv_arr = myFunc_realloc( argv_arr, &argv_elements);
}
argv_arr[argv_used] = NULL;
*argCTemp = argv_used;
*argVTemp = argv_arr;
return argv_used;
}
Some notes:
if an allocation fails, the program is terminated. You may need different error handling.
the passed in input string is 'corrupted'. This might not be an appropriate interface for your function (in general, I'd prefer that a function like this not destroy the input data).
the user of the function should call myFunc_free() to deallocate the returned array. Currently this is a simple wrapper for free(), but this gives you flexibility to do more sophisticated things (like allocating memory for the tokens so you don't have to destroy the input string).

Resources