2

I have an array of strings. I need to initialize each array element with some formatted data, i.e. each element should hold a constant string "data" plus a generated number. The final array should hold elements that look something like this, "data1", "data2", "data3", ... "dataN".

I used sprintf() but whenever the compile sees my sprintf() function, the program crashes. What am I doing wrong ?

//import necessary headers
#include <stdio.h>
#include <stdlib.h>

//variable to hold server data 
char *serverData[255];

//loop variable
int loop_index = 0;

//program entry
int main() {
    //initialize the serverData array elements with string "data" and
    //append number x to each element. i.e. x <= 255
    //use a for loop for the initialization
    for (; loop_index < sizeof(serverData) / sizeof(serverData[0]); loop_index++) {
        sprintf((char*)serverData[loop_index], "%s%d", "data", loop_index); //program crashes when this line is reached
    }
    return 0;
}
1
  • (char*)serverData[loop_index] - Only cast if you 1) fully understand why the cast is required 2) Know all implications and 3) accept all effects. Commented Feb 6, 2016 at 14:47

2 Answers 2

3

The problem here is, you're using serverData[n] while it is not assigned any valid memory. char *serverData[255]; being a global array of pointer type, each member is implicitly initialized to a null pointer.

Refer C11, chapter §6.7.9,

If an object that has static or thread storage duration is not initialized explicitly, then:

— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
- [.....]

A null pointer is not a valid one to access.

You need to allocate memory to serverData[n] before you can write to it. You can consider using malloc() to allocate memory to serverData[n] before you actually use it.

Sign up to request clarification or add additional context in comments.

Comments

0

Each pointer in your array is unitialized. Try this

#define NSERVERS    255
#define MAXDATA     32
char serverdata[MAXDATA][NSERVERS];

for (i = 0; i < NSERVERS; ++i)
    if (snprintf(serverdata[i], MAXDATA, "%s%d", "data", i) < 0)
        fprintf(stderr, "snprintf returns <0\n");

snprintf is recommended over sprintf, because it doesn't allow buffer overflows to occur. In this code, each element is initialized--you can't just write onto a pointer. To remove the limits of this array, we could use malloc, and realloc.

4 Comments

Using 1) snprintf() and not checking its results vs . 2) sprintf() trades one class of errors for another. Neither is recommended for robust code.
What's wrong with sprintf and snprintf? How does it trade one class of errors for another? What would be a better solutuon, then? @chux
What does snprintf() prevent that sprintf() may cause: buffer overflows. What does snprintf() without error checking do: Creates un-flagged invalid data in a string. char s[22]; snprintf(s, sizeof s, "Release prisoner %d", 123456789); --> "Release prisoner 1234", (Prisoner 1234 hates programmers) Simple check if the result of snprintf(s, n, format,...) is negative or >= n and then handle the error.
fixed [15 chars] @chux

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.