Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

166
Views
Can you pass a string by value in C?

Strings are interpreted as pointers when you pass them to a function in C, for example func(str) will pass a pointer to the block of memory named str. So by default, strings are already pointers when passing them into a function. Is there a way to pass a string by value where you don't have to end up manipulating the contents of str ?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

First, what is a string? It's an array of characters and then a \0. Just to make sure we all agree on that.

So the question is, can you pass an array of characters by value? And the answer is yes, but only if it's inside a struct or union:

struct String40Chars {
    char str[41];
};

void f(struct String40Chars s) {
    // s was passed by value - including s.str
}

However, you can't pass an array directly due to a historical quirk:

void f(char str[41]) {
    // you would think this would work,
    // but actually, the compiler converts it to void f(char *str)
}

That is unfortunate for people who really do want to pass arrays by value.

Luckily you usually don't need to. In every case I can think of, a pointer is good enough, and faster as well since it doesn't need to copy the array. Maybe you can elaborate on why you need to pass an array by value.

P.S. You talk about "strings being pointers" but that is nonsense. Strings are arrays. You can have pointers to arrays but the pointer is not the array.

over 4 years ago · Santiago Trujillo Report

0

The only way to achieve value semantics with string arguments in C is to have a struct or union that wraps the string.

Something like:

#define STR_BY_VALUE_MAX_LENGTH 128
typedef struct StrByValue_
{
    char str[STR_BY_VALUE_MAX_LENGTH];
} StrByValue;

void f(StrByValue strByVal)
{
    // Changes to strByVal will not affect the caller
}

Of course the caller will have to initialize the StrByValue object by copying the string (e.g. using strcpy) into the str field. You can also add a len field to the StrByValue struct if you don't want to use zero terminated strings.

over 4 years ago · Santiago Trujillo Report

0

Other answer are storing the string on the stack memory, which cannot be resized after initialization, which I don't think is a long runner. According to me string should be stored on heap memory so that we can expand it later, think something of a data structure that expands when something is appended at the end.

To implement this nicely and with some sugar syntax, we need to create 3 functions namely init_string(), append_string() and free_string().

  • init_string(): initialize the pointer and assign len = INIT_STR_LEN
  • append_string(): can be used for concatenation of two strings
  • free_string(): free the heap allocated ptr, hence no memory leaks

Code:

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

typedef struct
{
    char *ptr;
    size_t len;
} string;

string init_string(const char *s)
{
    string x;
    x.len = strlen(s);
    x.ptr = malloc(x.len + 1);
    if (!x.ptr)
    {
        fprintf(stderr, "err: memory can't be allocated\n");
        exit(EXIT_FAILURE);
    }
    memcpy(x.ptr, s, x.len + 1);
    return x;
}

void append_string(string *s, const char *str)
{
    if (!str || !s)
    {
        fprintf(stderr, "err: null was passed\n");
        exit(EXIT_FAILURE);
    }
    size_t str_l = strlen(str);
    s->ptr = realloc(s->ptr, s->len + str_l + 1);
    if (!s->ptr)
    {
        fprintf(stderr, "err: memory can't be allocated\n");
        exit(EXIT_FAILURE);
    }
    memcpy(s->ptr + s->len, str, str_l + 1);
    s->len += str_l;
}

void free_string(string *s)
{
    if (!s)
    {
        fprintf(stderr, "err: null was passed\n");
        exit(EXIT_FAILURE);
    }
    free(s->ptr);
    s->len = 0;
}

void foo(string a) // got the value of a
{
    // cannot modified permanently
}

void bar(string *a) // got the address of a
{
    // can be modified permanently
}

int main(void)
{
    string str = init_string("Hello world, I'm a c-string.");
    puts(str.ptr);
    append_string(&str, "stackoverflow");
    puts(str.ptr);
    free_string(&str);
    return EXIT_SUCCESS;
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!