Home > OS >  Loop of sprintf only outputing final looped value
Loop of sprintf only outputing final looped value

Time:12-29

I have an char* array. I loop through the correct index of the array to put numbers.

However, it seems that the value placed in the index is wrong. It seems to only store the last call to sprintf.

For instance, if I want the numbers 0, 1, 2, 3. However, it seems to return 3, 3, 3, 3.

I have placed a printf statement to see if there is an error, but it produces the correct numbers. I assume there must be a weird error when using sprintf with an array.

char* printArray[12];

for (int i = 1; i < 12 1; i  ) {
    char *printVal;
    char temp[10];
    sprintf(temp, "%d", i-1);
    printVal = temp;
    printf("%s\n", printVal);
    printArray[i-1] = printVal;
}
for (int i = 0; i < 12; i  ) {
    printf("%s\n", printArray[i]);
}

This is a simplified version. This produces the error. I have attempted to use strcpy but that results in the same error.

CodePudding user response:

The problem is that the memory for temp goes away when you leave each iteration of the for loop, so you can't save pointers to temp into printArray.

You need to make a dynamic copy of temp so you can save it outside the loop.

printArray should be an array of strings, not pointers, then you can use strcpy() to copy them.

char *printArray[12];

for (int i = 1; i < 12 1; i  ) {
    char temp[10];
    sprintf(temp, "%d", i-1);
    printf("%s\n", temp);
    printArray[i-1] = strdup(temp);
}

for (int i = 0; i < 12; i  ) {
    printf("%s\n", printArray[i]);
}

If you don't have strdup() available, it's simple:

char *my_strdup(const char *s) {
    char *new = malloc(strlen(s) 1);
    if (new) {
        strcpy(new, s);
    }
    return new;
}

CodePudding user response:

Undefined behavior (UB)

printArray[i-1] = printVal; repeatedly assigns the address of local object char temp[10];.

Later code attempts to print the data in this common, now invalid, address: result UB.


Instead of copying a pointer, copy the contents into memory.

// char* printArray[12];
#define INT_STRING_SIZE 12
char printArray[12][INT_STRING_SIZE];

...

for (int i = 0; i < 12; i  ) {
  snprintf(printArray[i], sizeof printArray[i], "%d", i);
}

If code must remain as char* printArray[12];, allocate memory.

for (int i = 0; i < 12; i  ) {
  char temp[INT_STRING_SIZE];
  int len = snprintf(temp, sizeof temp, "%d", i);
  printArray[i] = malloc(len   1);
  // Check for allocation omitted brevity.
  memcpy(printArray[i], temp, len   1);
  // or 
  strcpy(printArray[i], temp);
}

And free the memory when done.

  •  Tags:  
  • c
  • Related