Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 669941
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T00:12:25+00:00 2026-05-14T00:12:25+00:00

My function is being passed a struct containing, among other things, a NULL terminated

  • 0

My function is being passed a struct containing, among other things, a NULL terminated array of pointers to words making up a command with arguments.

I’m performing a glob match on the list of arguments, to expand them into a full list of files, then I want to replace the passed argument array with the new expanded one.

The globbing is working fine, that is, g.gl_pathv is populated with the list of expected files. However, I am having trouble copying this array into the struct I was given.

#include <glob.h>

struct command {
  char **argv;
  // other fields...
}

void myFunction( struct command * cmd )
{
  char **p = cmd->argv;
  char* program = *p++; // save the program name (e.g 'ls', and increment to the first argument

  glob_t g;
  memset(&g, 0, sizeof(g));
  g.gl_offs = 1;
  int res = glob(*p++, GLOB_DOOFFS, NULL, &g);
  glob_handle_res(res);
  while (*p)
  {
      res = glob(*p, GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
      glob_handle_res(res);
  }

  if( g.gl_pathc <= 0 )
  {
      globfree(&g);
  }

  cmd->argv = malloc((g.gl_pathc + g.gl_offs) * sizeof *cmd->argv);

  if (cmd->argv == NULL) { sys_fatal_error("pattern_expand: malloc failed\n");}
   // copy over the arguments
  size_t i = g.gl_offs;
  for (; i < g.gl_pathc + g.gl_offs; ++i)
      cmd->argv[i] = strdup(g.gl_pathv[i]);

  // insert the original program name
  cmd->argv[0] = strdup(program);
  ** cmd->argv[g.gl_pathc + g.gl_offs] = 0; **
  globfree(&g);
}

void 
command_free(struct esh_command * cmd)
{
    char ** p = cmd->argv;
    while (*p) {
        free(*p++); // Segfaults here, was it already freed?
    }
    free(cmd->argv);
    free(cmd);
}

Edit 1: Also, I realized I need to stick program back in there as cmd->argv[0]
Edit 2: Added call to calloc
Edit 3: Edit mem management with tips from Alok
Edit 4: More tips from alok
Edit 5: Almost working.. the app segfaults when freeing the command struct

Finally: Seems like I was missing the terminating NULL, so adding the line:

cmd->argv[g.gl_pathc + g.gl_offs] = 0;  

seemed to make it work.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T00:12:25+00:00Added an answer on May 14, 2026 at 12:12 am

    argv is an array of pointers of char *. This means that argv has space for argc char * values. If you try to copy more than that many char * values into it, you will end up with an overflow.

    Most likely your glob call results in more than argc elements in gl_pathv field (i.e, gl_pathc > argc). This is undefined behavior.

    It is similar to the code below:

    /* Wrong code */
    #include <string.h>
    
    int a[] = { 1, 2, 3 };
    int b[] = { 1, 2, 3, 4 };
    memcpy(a, b, sizeof b);
    

    Solution: you should either work with the glob_t struct directly, or allocate new space to copy gl_pathv to a new char **:

    char **paths = malloc(g.gl_pathc * sizeof *paths);
    if (paths == NULL) { /* handle error */ }
    for (size_t i=0; i < g.gl_pathc; ++i) {
        /* The following just copies the pointer */
        paths[i] = g.gl_pathv[i];
    
        /* If you actually want to copy the string, then
           you need to malloc again here.
    
           Something like:
    
           paths[i] = malloc(strlen(g.gl_pathv[i] + 1));
    
           followed by strcpy.
         */
    }
    
    /* free all the allocated data when done */
    

    Edit: after your edit:

    cmd->argv = calloc(g.gl_pathc, sizeof(char *) *g.gl_pathc);
    

    it should work, but each of argv[1] to argv[g.gl_pathc + g.gl_offs - 1] is a char * that is “owned” by the struct glob. Your memcpy call is only copying the pointers. When you later do globfree(), those pointers don’t mean anything anymore. So, you need to do copy the strings for your use:

    size_t i;
    cmd->argv = malloc((g.gl_pathc+g.gl_offs) * sizeof *cmd->argv);
    for (i=g.gl_offs; i < g.gl_pathc + g.gl_offs; ++i)
        cmd->argv[i] = strdup(g.gl_pathv[i]);
    

    This makes sure you now have your own private copies of the strings. Be sure to free them (and argv) once you are done.

    There are a few other problems with your code.

    1. You are doing *p++, you should do p++, since you’re not using the value of the dereferencing.
    2. You should really check the return value of glob.
    3. Your paths variable needs g.gl_pathc + 1 elements, not g.gl_pathc. (Or more correctly, you need to allocate g.gl_pathc + g.gl_offs times sizeof *paths bytes.)
    4. Your for loop to copy strings should be for (j=1; j < g.gl_pathc + g.gl_offs; ++j).
    5. Make sure you prevent shell from expanding your glob. I.e., call ./a.out '*' instead of ./a.out *.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to pass a function to another function. I think functions being passed
With a function being passed a full path to a file, such as C:\someFolder\anotherFolder\someXML.xml
I have a jquery object being passed to my function. In the function I
Let's say I have a function which is being passed a string which originally
I have an [object Object] being passed as an argument through a jQuery function
Question: How do I check if a function is being passed as a parameter?
I have seen that a prime number implementation of the GetHashCode function is being
I detoured LoadLibraryA, in order to block the function from being called into my
I have a function that is being called from different threads in the application.
I have a javascript function that is being built to animate the collapse of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.