Hello, I am working with variable arguments and I have no problem using them with Integer, Float or char arrays. But when I try to use String arrays, it is a multidimensional array and I am not sure ...

I am calling a function with variable arguments, one of which could be a string array. And the string array gets populated in the function. I get the right pointer to the first index, I can change its value properly inside the function but I cannot get to the second index, nor do I see the right pointer address for the second index. I think it has something to do with allocating right size memory but I'm a little confused.

Here is my test code -

int fetchroutStr(int numArgs, ...)
{
va_list arg_ptr;
int counter = 0;
int numParam = 0;
char *tempStr[100]; 
int args = 0;

va_start(arg_ptr, numArgs);
numParam = numArgs;

while(counter < numArgs)
{
tempStr[0] = va_arg(arg_ptr, char **);
printf("\nFetch Pointer : 0x%p", tempStr[0]);
printf("\nFetch Loop : %d - %s", counter, tempStr[0]);

// printf("\nPointer 0x%p", &tempStr[1]);
// printf("\nIn loop: %d - %s", counter, tempStr[1]);
counter++;
}
va_end(arg_ptr); 

strcpy(tempStr[0], "funcStr1");
printf("\nFetch Field changed: %s", tempStr[0]);
// strcpy(tempStr[1], "funcStr2");
// printf("\nfetch 2: %s", tempStr[1]);

}


void main() {
char testStr [10][20];

strcpy(testStr[0], "strMain1");
strcpy(testStr[1], "strMain2");
printf("\nMain Field 1: %s",testStr[0]);
printf("\nMain Field 2: %s",testStr[1]);

printf("\nMain Pointer 1: 0x%p", &testStr[0]);
printf("\nMain Pointer 2: 0x%p\n\n", &testStr[1]);

fetchroutStr(1, testStr); 
printf("\n\n\nMain After function Field 1: %s", testStr[0]);
printf("\nMain After function Field 2: %s \n\n", testStr[1]); 

}

Recommended Answers

All 4 Replies

>tempStr[0] = va_arg(arg_ptr, char **);
A two dimensional array is not compatible with a pointer to a pointer. Either switch to using an actual pointer to a pointer for your source, or pull the correct type from your varargs list:

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

void fetchroutStr(int numArgs, ...)
{
  va_list arg_ptr;
  int counter = 0;
  int numParam = 0;
  char *tempStr[100]; 

  va_start(arg_ptr, numArgs);
  numParam = numArgs;

  while(counter < numArgs)
  {
    void *p = va_arg(arg_ptr, void*);
    tempStr[0] = ((char(*)[20])p)[0];
    printf("\nFetch Pointer : 0x%p", tempStr[0]);
    printf("\nFetch Loop : %d - %s", counter, tempStr[0]);
    tempStr[1] = ((char(*)[20])p)[1];
    printf("\nPointer 0x%p", &tempStr[1]);
    printf("\nIn loop: %d - %s", counter, tempStr[1]);
    counter++;
  }
  va_end(arg_ptr); 

  strcpy(tempStr[0], "funcStr1");
  printf("\nFetch Field changed: %s", tempStr[0]);
  strcpy(tempStr[1], "funcStr2");
  printf("\nfetch 2: %s", tempStr[1]);
}

int main(void) {
  char testStr [10][20];

  strcpy(testStr[0], "strMain1");
  strcpy(testStr[1], "strMain2");
  printf("\nMain Field 1: %s",testStr[0]);
  printf("\nMain Field 2: %s",testStr[1]);

  printf("\nMain Pointer 1: 0x%p", &testStr[0]);
  printf("\nMain Pointer 2: 0x%p\n\n", &testStr[1]);

  fetchroutStr(1, testStr); 
  printf("\n\n\nMain After function Field 1: %s", testStr[0]);
  printf("\nMain After function Field 2: %s \n\n", testStr[1]); 

  return 0;
}

memory for that array is not layed out by pointers. The first 20 bytes are for the first string, that is followed by the next 20 bytes for the second string, etc. So fetchoutStr() needs to treat it as if it were just a single-dimension character array that can hold up to 10 20-byte strings.

int fetchroutStr(int numArgs, ...)
{
va_list arg_ptr;
int counter = 0;
int numParam = 0;
char *tempStr;
int args = 0;

va_start(arg_ptr, numArgs);
numParam = numArgs;

while(counter < numArgs)
{
tempStr = va_arg(arg_ptr, char *);
printf("\nFetch Pointer : 0x%p", tempStr);
printf("\nFetch Loop : %d - %s", counter, tempStr);

// printf("\nPointer 0x%p", &tempStr[1]);
// printf("\nIn loop: %d - %s", counter, tempStr[1]);
counter++;
}
va_end(arg_ptr);

strcpy(tempStr, "funcStr1");
printf("\nFetch Field 1 changed: %s", tempStr);
tempStr += 20; // advance to beginning of the next string
printf("\nFetch Field 2 changed: %s", tempStr);
strcpy(tempStr, "funcStr2");
// printf("\nfetch 2: %s", tempStr[1]);
return 0;
}

[edit] Or -- like Narue sayd ^^^ [/edit]

Thank u so much for your help. It works great. I had just not thought about using void * in va_arg and that had caused me a lot of confusion. Thanks again.

****************************************************

>tempStr[0] = va_arg(arg_ptr, char **);
A two dimensional array is not compatible with a pointer to a pointer. Either switch to using an actual pointer to a pointer for your source, or pull the correct type from your varargs list:

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

void fetchroutStr(int numArgs, ...)
{
  va_list arg_ptr;
  int counter = 0;
  int numParam = 0;
  char *tempStr[100]; 

  va_start(arg_ptr, numArgs);
  numParam = numArgs;

  while(counter < numArgs)
  {
    void *p = va_arg(arg_ptr, void*);
    tempStr[0] = ((char(*)[20])p)[0];
    printf("\nFetch Pointer : 0x%p", tempStr[0]);
    printf("\nFetch Loop : %d - %s", counter, tempStr[0]);
    tempStr[1] = ((char(*)[20])p)[1];
    printf("\nPointer 0x%p", &tempStr[1]);
    printf("\nIn loop: %d - %s", counter, tempStr[1]);
    counter++;
  }
  va_end(arg_ptr); 

  strcpy(tempStr[0], "funcStr1");
  printf("\nFetch Field changed: %s", tempStr[0]);
  strcpy(tempStr[1], "funcStr2");
  printf("\nfetch 2: %s", tempStr[1]);
}

int main(void) {
  char testStr [10][20];

  strcpy(testStr[0], "strMain1");
  strcpy(testStr[1], "strMain2");
  printf("\nMain Field 1: %s",testStr[0]);
  printf("\nMain Field 2: %s",testStr[1]);

  printf("\nMain Pointer 1: 0x%p", &testStr[0]);
  printf("\nMain Pointer 2: 0x%p\n\n", &testStr[1]);

  fetchroutStr(1, testStr); 
  printf("\n\n\nMain After function Field 1: %s", testStr[0]);
  printf("\nMain After function Field 2: %s \n\n", testStr[1]); 

  return 0;
}

Thanks. It works ....

Thank u so much for your help. It works great. I had just not thought about using void * in va_arg and that had caused me a lot of confusion. Thanks again.

****************************************************

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.