Declare a struct with zero values instead of random memory? - c

I have a struct like this:
typedef struct string {
unsigned long length;
unsigned *data;
} string;
Can I write something so that when I do this:
string s;
the length property is zero, instead of whatever happens to be in the memory? data works well, as it's preset to zero or a null pointer.
Example of what happens right now:
string s;
printf("length: %lu\n", s.length);
printf("pointer: %lu\n", (unsigned long) s.data);
Result:
length: 140737488347584
pointer: 0
I want to avoid having to call an initialisation function on each new string just to set length to zero.
More information
Now that I think about it, it may not be really necessary to do this in my particular case (though it would be nice) because most people would initially set the string through ctou (which imports UTF-8 from char pointer) and that function sets length to zero anyway.

You could use
string s = {0,NULL};

To combine the two previous answers (sort of) I'd define something like
#define STRING_INITIALIZER {0, NULL}
.
.
string s = STRING_INITIALIZER;
BTW, your struct declaration itself looks weird for a string. Either this is not a string as we usually understand it in C but merely a dynamic array of unsigned, or it is really a string and then this should be char*.

The accepted answer answered the question that you asked, but didn't address whether you ought.
Your string is a class and has class semantics. The initializer may be fine for kernel code where every last instruction counts, but in application code your static initializers are ugly and error prone.
It is possible to write classes in C, the stdio FILE type is a fabulous example, and here is the same idea applied to your string class:
typedef struct {
int length;
char *data;
} String;
String *sopen() {
String *s = malloc(sizeof(String));
if(s) {
s->length = 0;
s->data = NULL;
}
return s;
}
int sclose(String *s) {
free(s->data);
free(s);
return 0;
}
int main()
{
String *s = sopen();
return sclose(s);
}
Where I've followed the FILE* function name style for metaphoric reasons. Yep, there's more code. Yep, you have to explicitly deallocate the structure; but note that even though you were counting on auto class initialization in your code sample, if data was ever allocated, you couldn't count on leaving scope to automatically deallocate the storage for you.
This approach also has the merit of abstracting the type of data from the users of the class. As there seems to be some confusion about what type you really want to use, this flexibility may come in handy.

#define DEFINE_STRING(s) string s = {0, NULL}
{
DEFINE_STRING(s);
}
You can use a macro to "do this automatically"

Related

C - Append strings until end of allocated memory

Let's consider following piece of code:
int len = 100;
char *buf = (char*)malloc(sizeof(char)*len);
printf("Appended: %s\n",struct_to_string(some_struct,buf,len));
Someone allocated amount of memory in order to get it filled with string data. The problem is that string data taken from some_struct could be ANY length. So what i want to achieve is to make struct_to_string function do the following:
Do not allocate any memory that goes outside (so, buf has to be allocated outside of the function, and passed)
Inside the struct_to_string I want to do something like:
char* struct_to_string(const struct type* some_struct, char* buf, int len) {
//it will be more like pseudo code to show the idea :)
char var1_name[] = "int l1";
buf += var1_name + " = " + some_struct->l1;
//when l1 is a int or some non char, I need to cast it
char var2_name[] = "bool t1";
buf += var2_name + " = " + some_struct->t1;
// buf+= (I mean appending function) should check if there is a place in a buf,
//if there is not it should fill buf with
//as many characters as possible (without writting to memory) and stop
//etc.
return buf;
}
Output should be like:
Appended: int l1 = 10 bool t1 = 20 //if there was good amount of memory allocated or
ex: Appended: int l1 = 10 bo //if there was not enough memory allocated
To sum up:
I need a function (or couple of functions) that adds given strings to the base string without overwritting base string;
do nothing when base string memory is full
I can not use C++ libraries
Another things that I could ask but are not so important right now:
Is there a way (in C) iterate through structure variable list to get their names, or at least to get their values without their names? (for example iterate through structure like through array ;d)
I do not normally use C, but for now I'm obligated to do, so I have very basic knowledge.
(sorry for my English)
Edit:
Good way to solve that problem is shown in post below: stackoverflow.com/a/2674354/2630520
I'd say all you need is the standard strncat function defined in the string.h header.
About the 'iterate through structure variable list' part, I'm not exactly sure what you mean. If your talking about iterating over the structure's members, a short answer would be : you can't introspect C structs for free.
You need to know beforehand what structure type you're using so that the compiler know at what offset in the memory it can find each member of your struct. Otherwise it's just an array of bytes like any other.
Don't mind asking if I wasn't clear enough or if you want more details.
Good luck.
So basically I did it like here: stackoverflow.com/a/2674354/2630520
int struct_to_string(const struct struct_type* struct_var, char* buf, const int len)
{
unsigned int length = 0;
unsigned int i;
length += snprintf(buf+length, len-length, "v0[%d]", struct_var->v0);
length += other_struct_to_string(struct_var->sub, buf+length, len-length);
length += snprintf(buf+length, len-length, "v2[%d]", struct_var->v2);
length += snprintf(buf+length, len-length, "v3[%d]", struct_var->v3);
....
return length;
}
snprintf writes as much as possible and discards everything left, so it was exactly what I was looking for.

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

Sacrificing expression of intent for memory management

I'm pretty new at C programming, and this type of thing keeps popping up. As a simple example, suppose I have a struct http_header with some char pointers:
struct http_header {
char* name;
char* value;
};
I want to fill an http_header where value is the string representation of an int. I "feel" like, semantically, I should be able to write a function that takes in an empty header pointer, a name string, and an int and fills out the header appropriately.
void fill_header(struct http_header *h, char* name, int value)
{
h->name = name;
char *value_str = malloc(100);
sprintf(value_str, "%d", value);
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int val = 42;
fill_header(&h, name, val);
...
free(h.value);
}
Here, the calling code reads exactly as my intent, but in this case I'm creating the value string dynamically, which means I'd have to free it later. That doesn't smell right to me; it seems like the caller then knows too much about the implementation of fill_header. And in actual implementations it may not be so easy to know what to free: consider filling an array of http_headers where only one of them needed to have its value malloced.
To get around this, I'd have to create the string beforehand:
void fill_header2(struct http_header *h, char* name, char *value_str)
{
h->name = name;
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int value = 42;
char value_str[100];
sprintf(value_str, "%d", value);
fill_header2(&h, name, value_str);
}
As this pattern continues down the chain of structures with pointers to other structures, I end up doing so much work in top level functions the lower level ones seem hardly worth it. Furthermore, I've essentially sacrificed the "fill a header with an int" idea which I set out to write in the first place. I'm I missing something here? Is there some pattern or design choice that will make my life easier and keep my function calls expressing my intent?
P.S. Thanks to all at Stackoverfow for being the best professor I've ever had.
Well, I would go with the first approach (with a twist), and also provide a destroy function:
struct http_header *make_header(char *name, int value)
{
struct http_header *h = malloc(sizeof *h);
/* ... */
return h;
}
void destroy_header(struct http_header *h)
{
free(h->name);
free(h);
}
This way the caller doesn't have to know anything about http_header.
You might also get away with a version that leaves the main allocation (the struct itself) to the caller and does it's own internal allocation. Then you would have to provide a clear_header which only frees that fill allocated. But this clear_header leaves you with a partially-valid object.
I think your problem is simply that you are programming asymmetrically. You should once and for all decide who is responsible for the string inside your structure. Then you should have two functions, not only one, that should be called something like header_init and header_destroy.
For the init function I'd be a bit more careful. Check for a 0 argument of your pointer, and initialize your DS completely, something like *h = (http_header){ .name = name }. You never know if you or somebody will end up in adding another field to your structure. So by that at least all other fields are initialized with 0.
If you are new at C programming, you might perhaps want to use the Boehm's conservative garbage collector. Boehm's GC works very well in practice, and by using it systematically in your own code you could use GC_malloc instead of malloc and never bother about calling free or GC_free.
Hunting memory leaks in C (or even C++) code is often a headache. There are tools (like valgrind) which can help you, but you could decide to not bother by using Boehm's GC.
Garbage collection (and memory management) is a global property of a program, so if you use Boehm's GC you should decide that early.
The general solution to your problem is that of object ownership, as others have suggested. The simplest solution to your particular problem is, however, to use a char array for value, i.e., char value[12]. 2^32 has 10 decimal digits, +1 for the sign, +1 for the null-terminator.
You should ensure that 1) int is not larger than 32-bits at compile-time, 2) ensure that the value is within some acceptable range (HTTP codes have only 3 digits) before calling sprintf, 3) use snprintf.
So by using a static array you get rid of the ownership problem, AND you use less memory.

Pointers to variables?

Is it possible to have pointers to data variables? I know I can have, say, pointers to strings e.g. char *str[n] and I can perform a 'for' loop over those pointers to retrieve the strings ... str[i] where i is the index counter.
If I have some data e.g.
char var1;
int var2;
char var3;
and I wanted to get data from stdin I might use 3 separate calls to scanf()- just an example - to populate these variables.
Can I have 'an array of pointers to data' e.g. void *data[] where data[0] = char var1, data[1] = int var2 and data[2] = char var3, so that I could then use a single call to scanf() in a 'for' loop to populate these variables? (I'm assuming the type would have to be void to cater for the different types in the array)
I don't really recommend this, but here's the implementation you describe:
char var1;
int var2;
char var3;
void *vars[3];
char *types[3];
vars[0]=&var1; types[0]="%c";
vars[1]=&var2; types[1]="%d";
vars[2]=&var3; types[2]="%c";
for (int i=0;i<3;i++)
{
scanf(types[i],vars[i]);
}
You need the array of types so that scanf knows what it should expect.
However, this procedure is extremely unsafe. By discarding any type-safety, you invite crashes from malformed input. Also, if you misconfigure types[] then you will almost certainly crash, or see unexpected results.
By the time you've set up the arrays, have you really saved any code?
There are plenty of answers here that will allow you to use either a type-safe C++ solution, or as others have recommended, calling scanf() explicitly.
You certainly could have such a void *data[] array. You wouldn't be able to read those in via scanf, though, as you need a different format specifier for the different data types.
If you wanted to do this, you could iterate over an array of
struct dataType
{
void *data;
char *format_specifier;
}
or somesuch. However, I doubt this would be a good idea - you probably want to also prompt for each value, so you'd add another char *prompt to that struct, and you'll probably need other things later as well.
I suspect the code you'd end up writing to do this would be much more effort than simply scanf-ing n times, even for quite large n.
The problem is that this void * array would be dealing with datatypes of different sizes. For this problem, you'd probably want to use a struct and maintain an array of those instead. Or you could just put your data in as a byte array, but then you'd have to know how to "chop it up" properly.
you could have an array of void*, so *array[0] = var1, etc.
To illustrate the problem..
int main(int argc, char* argv[])
{
char var1 = 'a';
int var2 = 42;
char var3 = 'b';
void* stuff[3] = {0};
stuff[0] = &var1;
stuff[1] = &var2;
stuff[2] = &var3;
// Can't really use the array of void*'s in a loop because the
// types aren't known...
assert( var1 == (char)(*(char*)stuff[0]));
assert( var2 == (int)(*(int*)stuff[1]));
assert( var3 == (char)(*(char*)stuff[2]));
return 0;
}
Not directly, no. If you're able to use C++ in this situation, the closest you could do would be to wrap each variable in an object (either something like a variant_t or some templated, polymorphic solution). For instance, I believe you can do something like this:
class BaseType
{
public:
virtual void DoScanf();
};
template<typename TYPE>
class SubType : public BaseType
{
public:
SubType(const TYPE& data) : m_data(data) {}
const TYPE& m_data;
virtual void DoScanf()
{
// Your code here
}
};
int num1;
char char1;
SubType<int> num1Wrapper(num1);
SubType<char> char1Wrapper(char1);
// You can then make a list/vector/array of BaseTypes and iterate over those.
Looks like you are trying to implement a template (C++) equivalent in C. :D exactly that is what i am trying to do, for one of my project. I think mine case is less confusing as I am using only one datatype (some project specific structure), mine array would not be intermixing the datatypes.
Hey, do one thing try using a union of various data-types you intent to use, i think reading this shall not be a problem. As when your read-function using that union reads it, will be able to read it, because of the inherit C-type safety. What i mean here is the follow the same concept which we usually use to check a endianess of a machine.
These are few idea, i am myself working on, shall be able to complete this is a day or two. And only then i can tell you, if this is exactly possible or not. Good luck, if you are Implementing this for some project. Do share your solution, may be here itself, I might also find some answer. :)
I am using the array of void pointers.
If you want an array of variables that can be "anything" and you are working in C, then I think you want something like a struct that contains a typeid and a union.
Like this, maybe: (Note, quick example, not compile tested, not a complete program)
struct anything_t {
union {
int i;
double d;
char short_str[7]; /* 7 because with this and typeid makes 8 */
char *str; /* must malloc or strdup to use this */
}; /* pretty sure anonymous union like this works, not compiled */
char type; /* char because it is small, last because of alignment */
};
char *anything_to_str(char *str, size_t len, const struct anything_t *any)
{
switch(any->type) {
case 1: snprintf(str, len, "%d", any->i); break;
case 2: snprintf(str, len, "%f", any->d); break;
case 3: snprintf(str, len, "%.7s", any->short_str); break; /* careful, not necessarily 0-terminated */
case 4: snprintf(str, len, "%s", any->str); break;
default: abort(); break;
}
return str;
}
And I forgot to add the scanf part I intended:
char *scanf_anything(struct anything_t *inputs, size_t count)
{
int input_i;
struct anything_t *i;
for(input_i=0; input_i<count; ++input_i) {
any = inputs + input_i;
switch(any->type) {
case 1: scanf(" %d ", any->i); break;
case 2: scanf(" %lf ", any->d); break;
case 3: scanf(" %.6s ", any->short_str); break;
case 4: scanf(" %a ", any->str); break; /* C99 or GNU but you'd be a fool not to use it */
default: abort(); break;
}
}
}
Formally all the solutions presented here which are using void* have the same problem. Passing a void* as a variadic argument (like scanf) which expects another type of pointer put you in the "undefined behavior" domains (for the same reason, you should cast NULL to the correct type when passed as variadic argument as well).
on most common platforms, I see no reason for a compiler to take advantage of that. So it will probably work until a compiler maker find out that there is a test in SPEC where it allows to get a 0.000001% improvement :-)
on some exotic platforms, taking advantage of that is the obvious thing to do (that rule has been put for them after all; they are mostly of historical interest only but I'd not bet anything about embedded platforms; I know, using scanf on embedded platforms can be considered as strange)
All solutions above are valid but no one has yet mentioned that you can do what you want with a single simple scanf call:
scanf(%c%d%c",var1,var2,var3);

In C: How to set a pointer to a structure member that is an array?

How should I write my code to example a specific array index of an array that happens to be a member of a structure? The following code is giving me problems.
// main.c
void clean_buffers(void); // prototype
struct DEV_STATUS {
unsigned char ADDR;
unsigned char DEV_HAS_DATA;
unsigned char ETH_HAS_DATA;
unsigned char DATA[20];
};
struct DEV_STATUS g_cmdQueue[60] = {0};
void main(void) {
clean_buffers();
while (1) {
;// MCU tasks
}
}
void clean_buffers(void) {
unsigned char theCount = 0;
byte queIdx;
for (queIdx = 0; queIdx < 59; queIdx++) {
struct DEV_STATUS *p_struct;
unsigned char *p_data;
p_struct = &g_cmdQueue[queIdx];
p_data = &p_struct->DATA;
p_struct->ADDR = 0;
p_struct->DEV_HAS_DATA = 0;
p_struct->ETH_HAS_DATA = 0;
theCount = 0;
while(*(p_data+theCount) != 0) {
*(p_data+(theCount++)) = 0;
}
}
} // EOF main.c
I get a compiler error "struct/union member expected" on the following line:
p_data = &p_struct->DATA;
How should I write a pointer if I was to access, for example, the specific value of structure member DATA[3]? I'm confused, I thought that as p_data = &p_struct->DATA; is defined, I should be able to get it by using *(pdata+3) but I guess I'm missing something.
Are you sure you are compiling the same code you posted here?
If your compiler complains at this line
p_data = &p_struct->DATA;
with a "struct/union member expected" message, your compiler is probably broken.
Note, that &p_struct->DATA is a perfectly valid expression in C. There's absolutely no problems with this expression by itself.
The problem here is just that this is not what you need in your case. &p_struct->DATA returns a pointer to the entire array 'DATA', i.e a pointer of type unsigned char (*)[20]. You are trying to assign this value to a pointer of type unsigned char *. This is illegal in C, since the types are completely different, but traditionally C compilers responded to it with a mere "type mismatch" warning and performed an implicit conversion (which, BTW, means that your original code, albeit "dirty", should still work as intended).
Even if some compiler decides to flag this mismatch as an error (which is fine), it still should not complain about any problems of "struct/union member expected" kind. There's no such problems here.
P.S. As other already said, what you really need is p_data = &p_struct->DATA[0], but that still does not explain your compiler's strange behavior. Could it be that 'DATA' is a macro defined somewhere before the 'clean_buffers' definition?
Added 10/19/2009: Nate, in your code you access your array using an index theCount. Since you are using the index access anyway, there's really no reason to even create the pointer you are trying to create. The code will work perfectly fine without any additional pointer, just acess the DATA field directly
theCount = 0;
while (p_struct->DATA[theCount] != 0) {
p_struct->DATA[theCount++] = 0;
(I'd probably use a for cycle here).
If you really insist on creating this pointer and still using the index access, the code should look something like the following (the others already suggested that more than once)
p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
theCount = 0;
while (p_data[theCount] != 0) {
p_data[theCount++] = 0;
Moreover, you can opt for a more "exotic" variant :)
unsigned char (*p_data)[20]; /* <- note: declared differently */
...
p_data = &p_struct->DATA; /* <- note: your original version */
...
theCount = 0;
while ((*p_data)[theCount] != 0) {
(*p_data)[theCount++] = 0;
However, returning to a unsigned char *p_data version, since you create that pointer, it might make more sense to use a "sliding pointer" technique instead of using index access
unsigned char *p_data;
...
p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
while (*p_data != 0) {
*p_data++ = 0;
As always, it is all a matter of personal preference. Of course, nothing of this will work until you get rid of that interference from the macro.
Lose the & in
p_data = &p_struct->DATA;
p_struct is already a pointer. Afterwards, use p_data[] to access your array.
What you should write is one of two things:
p_data = p_struct->DATA; // DATA is the address of the first element.
OR
p_data = &p_struct->DATA[0]; // taking the address of the first element.
Simply remove the & at the beginning, like this:
p_data = p_struct->DATA;
That is special sintax for arrays (remember they are passed always as reference) and it is equivalent to:
p_data = &p_struct->DATA[0];
And yes, now you can use *(pdata+3)
Hope it helps.
Oops! Thank you AndreyT
struct DEV_STATUS *p_struct;
unsigned char *p_data;
p_struct = &g_cmdQueue[queIdx];
p_data = &p_struct->DATA;
p_struct is a pointer to struct DEV_STATUS.
&p_struct is the address of a pointer to struct DEV_STATUS (or a pointer to a pointer to a struct DEV_STATUS).
You probably want to change that line to
p_data = p_struct->DATA;
Oh ... your clean_buffers() function does not "clean" the element g_cmdQueue[59].
And, because it is a global object, the array g_cmdQueue is initialized to all zeros even before the first statement of main() exceutes.

Resources