sprintf y asignación de memoria

I have a structure where I stored some values as shown below:

struct cmd { 
    char *pname;
    char *pdesc;
}; 

Following initialization I made as:

struct cmd[] = {{"show", "show items"},
                {"exit", "exit the shell"},
                {"setitem",   "setting item"}
               };    

Estoy usando sprinf() to print by storing all the pname ans pdesc as below,

int length = 0;    
char *resultcmd;    
for (indx = 0; indx< cmdCount; indx++) {
     length += sprintf(resultcmd+length, cmd[indx].pname, cmd[indx].pdesc);    
}    

Please help me how to allocate memory for resultcmd, It worked when i make resulecmd as array of some length, but if more pname and pdesc are added buffer overruns. Please help me.

preguntado el 27 de noviembre de 13 a las 08:11

Use strlen to compute string length. -

Can you count up the total memory needed before hand? -

si usa glibc and not caring about portability to other libc implementations, will say stick with gcc, you might like to take a look at asprinf(). -

2 Respuestas

If you want safely output data to buffer resultcmd you have to find out its length before and use it:

size_t length = 1; // 1 symbol needed to store \0', 
                   // because strlen() returns length 
                   // without NULL-termination symbol
// compute length:
for (intx = 0; indx < cmdCount; indx++) {
     length += strlen(cmd[indx].pname) + strlen(cmd[indx].pdesc);
}

char *resultcmd = malloc(length);
int written = 0, ret = 0;

// print cmds to C string
for (indx = 0; indx < cmdCount; indx++) {
     ret = snprintf (resultcmd + written, length - written, 
                     "%s%s", cmd[indx].pname, cmd[indx].pdesc))
     if (0 > ret) {
         fprintf (stderr, "snprintf() error: %s\n", strerror(errno));
         break;
     } else {
         written += ret;
     }
}
/* 
 * some useful code here
 */
free(resultcmd);

respondido 27 nov., 13:13

don't you need the format argument for sprintf? sprintf(resultcmd+length, cmd[indx].pname, cmd[indx].pdesc); should be sprintf(resultcmd+length, "%s%s", cmd[indx].pname, cmd[indx].pdesc); In reality, it should be a format that looks nice... - Thang

@thang Thanks. Fixed. Moreover, pdesc will not be printed at all without format parameter. - Michael

@Michael I think your usage of length is wrong. From the malloc() on, you either should reset it or use a 2nd "cursor" variable. - glglgl

Prefiero hacer int crsr = 0; for (indx = 0; indx< cmdCount; indx++) { crsr += snprintf(resultcmd+crsr, length-crsr, "%s%s", ...); } in order to retain the original length and to have a bit of added safety. - glglgl

@glglgl Thanks to all again! Added all your ideas to the answer. Must be fine now. - Michael

Puedes usar snprintf(char *dest, size_t maxlen, char *fmt, ...) to bound the size of your print. If the function fails, it returns the number of characters that would have been written, had there been enough space; so that +1 is what you need to realloc.

respondido 27 nov., 13:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.