Char * function return

I have a function:

char *zap(char *ar) {

    char pie[100] = "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '";
    char dru[] = "' )";
    strcat(pie, ar);
    strcat(pie, dru);
    return pie;
}

and basically there are:

printf("%s", zap( argv[1] )  );

When compiling, I get a warning:

test.c: In function ‘zap’:
test.c:17: warning: function returns address of local variable

How do I return char * propertytly?

+5
source share
9 answers

It is best not to return it - instead pass the buffer you want to fill as a parameter.

void zap(char * pie, const char *ar) {
    strcpy( pie, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '");
    char dru[] = "' )";
    strcat(pie, ar);
    strcat(pie, dru);
}

Then name it like this:

char pie[100];
zap( pie, "foo" );

To skip this function, you also need to pass the length for the buffer, and then check this every time you are going to add a new query element.

+18
source

The published solutions all work, but just to answer your question about why you get a warning:

pie , , . . , ( ), -, , . , , , .

c-, , malloc ( ). , , . , google, C .

+12

pie malloc

+4
#include <assert.h>
#include <stdio.h>

/**
 * Returns the buffer, just for convenience.
 */
char *generateSQL(char *buf, size_t bufsize, const char *ar) {
    int n;

    n = snprintf(buf, bufsize, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '%s')", ar);
    /* FIXME: Properly escape the argument, just in case it contains an apostrophe. */
    assert(0 <= n && (unsigned) n < bufsize);
    return buf;
}

int main(int argc, char **argv)
{
    char buffer[4096];

    assert(1 < argc);
    printf("%s\n", generateSQL(buffer, sizeof(buffer), argv[1]));
    return 0;
}
+4
char pie[100];

void zap(char* pie, char *ar) {

    char pies[100] = "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '";
    char dru[] = "' )";
    strcpy(pie, pies);
    strcat(pie, ar);
    strcat(pie, dru);
}

zap(pie, argv[1]);
printf("%s", pie  );
+2

, , . , .. malloc, , .

+2

char

static char pie[100] = "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '";
+1

:

void zap(char **stmt, char *argument, size_t *stmtBufLen)
{
  char *fmt="INSERT INTO test(nazwa, liczba) VALUES ('nowy wpis', '%s')";
  /**
   * Is our current buffer size (stmtBufLen) big enough to hold the result string?
   */
  size_t newStmtLen = strlen(fmt) + strlen(argument) - 2;
  if (*stmtBufLen < newStmtLen)
  {
    /**
     * No.  Extend the buffer to accomodate the new statement length.
     */
    char *tmp = realloc(*stmt, newStmtLen + 1);
    if (tmp)
    {
      *stmt = tmp;
      *stmtLen = newStmtLen+1;
    }
    else
    {
      /**
       * For now, just write an error message to stderr; the statement
       * buffer and statement length are left unchanged.
       */
      fprintf(stderr, "realloc failed; stmt was not modified\n");
      return;
    }
  }
  /**
   * Write statement with argument to buffer.
   */
  sprintf(*stmt, fmt, argument);
}

int main(void)
{
  char *stmtBuffer = NULL;
  size_t stmtBufferLen = 0;
  ...
  zap(&stmtBuffer, "foo", &stmtBufferLen);
  ...
  zap(&stmtBuffer, "blurga", &stmtBufferLen);
  ...
  zap(&stmtBuffer, "AReallyLongArgumentName", &stmtBufferLen);
  ...
  zap(&stmtBuffer, "AnEvenLongerRidiculouslyLongArgumentName", &stmtBufferLen);
  ...
  free(stmtBuffer);
  return 0;
}

, NULL (realloc (NULL, size) == malloc (size)). , , , " ". , , ( , 10 , d - ).

0

, , , :

const int max_pie_cnt = 100;
const char *zap(char *ar) {

    static __declspec(thread) char pie[max_pie_cnt]; // use TLS to store buffer
    strcpy(pie, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '");
    char dru[] = "' )";
    strcat(pie, ar);
    strcat(pie, dru);
    return pie;
}

.

Btw, .

0
source

All Articles