-1

I have an error when try output a lot of variable via printf.

unsigned int vmID = 11;
char vm_title[512] = "title-123qwe";
unsigned int vm_cpu = 2;
unsigned int vm_ram = 12;
char vm_serveces[2048] = "123456789qweertrty";
char vm_notes[2048] = "wertyuio2345678";
unsigned int vm_vc = 3;
unsigned int vm_dc = 12;
unsigned int vm_cl = 6;
unsigned int vm_pl = 32;
unsigned int vm_os = 0;

printf("name='%s', cpu='%d', ram='%d', services='%s', notes='%s', vcname='%d', dcname='%d', clname='%d', poolname='%d', os='%d' id='%d';", vm_title, vm_cpu, vm_ram, vm_serveces, vm_notes, vm_vc, vm_dc, vm_cl, vm_pl, vm_os, vmID);

But But individually or in small groups work right:

printf("name='%s,", vm_title);
printf("cpu='%d',", vm_cpu);
printf("ram='%d',", vm_ram);
printf("services='%s',", vm_serveces);
printf("notes='%s',", vm_notes);
printf("vc='%d',", vm_vc);
printf("dc='%d',", vm_dc);
printf("cl='%d',", vm_cl);
printf("pl='%d',", vm_pl);
printf("os='%d';", vm_os);

I wait: "name='title-123qwe', cpu='2', ram='12', services='123456789qweertrty', notes='wertyuio2345678', vcname='3', dcname='12', clname='6', poolname='32', os='0' id='11', name='title-123qwe';"

P.S. For my task I use construction such as (not work too):

int len = snprintf(NULL,0, "xxx", yyy);
char *somevar = malloc(len + 1);
sprintf(somevar, "xxx", yyy);

What wrong? Is it possible to use a single call or will have to glue variable in a few hits?

Hm. I create a new file:

#include <stdlib.h>
#include <string.h>

int main () {
unsigned int vmID = 11;
char vm_title[512] = "title-123qwe";
unsigned int vm_cpu = 2;
unsigned int vm_ram = 12;
char vm_serveces[2048] = "123456789qweertrty";
char vm_notes[2048] = "wertyuio2345678";
unsigned int vm_vc = 3;
unsigned int vm_dc = 12;
unsigned int vm_cl = 6;
unsigned int vm_pl = 32;
unsigned int vm_os = 0;

// vc_ram = vm_pl + vm_vc;

printf("name='%s', cpu='%d', ram='%d', services='%s', notes='%s', vcname='%d', dcname='%d', clname='%d', poolname='%d', os='%d' id='%d';", vm_title, vm_cpu, vm_ram, vm_serveces, vm_notes, vm_vc, vm_dc, vm_cl, vm_pl, vm_os, vmID);

printf("name='%s,", vm_title);
printf("cpu='%d',", vm_cpu);
printf("ram='%d',", vm_ram);
printf("services='%s',", vm_serveces);
printf("notes='%s',", vm_notes);
printf("vc='%d',", vm_vc);
printf("dc='%d',", vm_dc);
printf("cl='%d',", vm_cl);
printf("pl='%d',", vm_pl);
printf("os='%d';", vm_os);

return 0;
}

It's work fine.

BUT if I uncomment string vc_ram = vm_pl + vm_vc; = segfault

Any manipulations with variables and I have fail.

Irbis
  • 51
  • 9
  • I guess you've corrupted the malloc arena, and that's why the crash happens when printf needs to malloc more memory, or sth. – Antti Haapala -- Слава Україні Dec 28 '17 at 09:02
  • 1
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a [mcve]. – DevSolar Dec 28 '17 at 09:02
  • 1
  • Compile with all warnings and debug info: `gcc -Wall -Wextra -g` with [GCC](http://gcc.gnu.org/). Read [documentation](http://en.cppreference.com/w/c) of every standard C function. Improve the code to get no warnings. **use the debugger `gdb`** (and [valgrind](http://valgrind.org/)). You probably have some [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) somewhere – Basile Starynkevitch Dec 28 '17 at 09:39

2 Answers2

1

It certainly is possible to chain together a lot of variables for printing, you just have to make sure your format string matches the arguments given, lest you get into undefined behaviour territory.

What you have in your simplified code should work fine, leading me to believe you may have simplified it too much. I would suggest posting the actual code that causes the problem (a full, able-to-be-compiled program, exhibiting the errant behaviour) since there's absolutely nothing wrong with what you're given us. The data is being set correctly and the printf is being called correctly.

I've seen implementations of printf (such as in embedded systems) that have limitations such as 4K maximum buffer size but you're nowhere near that.


However, look at your (original, now changed) code:

int len = snprintf(NULL,0, "xxx", yyy);
char *somevar = malloc(len + 1);
sprintf(NULL,0, "xxx", yyy);

If that truly is how you're doing it, I'm not surprised you're crashing - you don't actually populate the memory that you're allocating, meaning it will be set to some arbitrary value, including possible a non-null-terminated "string".

In any case, sprint is not like snprintf, it doesn't really like a NULL buffer being passed in.

The third line should be of the form:

sprintf(somevar, "xxx", yyy);

And, on top of that, though unlikely in a small program, malloc is allowed to fail and return NULL - you should always check for failure before relying on values from C functions.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

I have an error when try output a lot of variable via printf.

The error is probably elsewhere. You are allowed to give many arguments (probably hundreds or thousands of them, the limit is implementation specific and quite high in practice) to printf, if the format control string (first argument to printf) is conforming the the other arguments (in number of argument and in type), and if the arguments are all valid. Otherwise, it is undefined behavior. Be very scared of UB (and you probably have some).

You should compile with all warnings and debug info, e.g. gcc -Wall -Wextra -g with GCC, and improve your code to get no warnings. You should read the documentation of every standard C function, and of every external function you are using.

Use the debugger gdb to run your program step by step and query its state, then understanding what is wrong. You might also use tools like valgrind to hunt memory leaks, buffer overflows, and other memory corruption (and you probably have some) etc.

Your bug is probably in some other code that your question don't show.

BTW, you might use asprintf(3) if your system has it, and you should test against failure of malloc.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547