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

  • Home
  • SEARCH
  • 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 6117861
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T15:22:09+00:00 2026-05-23T15:22:09+00:00

I am having some issues with a program I am writing in C, and

  • 0

I am having some issues with a program I am writing in C, and I have surpassed my knowledge. In summary, I need to deep copy a link list from one list to another. The lists have malloc’d data in them and I need to preserve all the data without having pointers pointing at the same information.

I have only posted the code that I think is relevant. If I am missing any important contextual information please let me know.

Here is the code:

matrix.h

typedef struct matrix {
        char *name;
        int R;
        int C;
        int dim;
        void (*concat_matrices)( struct matrix *A, struct matrix *B, struct matrix *ret );
} Matrix;

void concat_matrices( Matrix *A, Matrix *B, Matrix *ret ) {
        int L1 = strlen( A->name );
        int L2 = strlen( B->name );
        int len = L1 + L2;
        char *Ap = (char*)malloc(L1*sizeof(char)); strcpy(Ap,A->name);
        char *Bp = (char*)malloc(L2*sizeof(char )); strcpy(Bp,B->name);
        char *c = (char*)malloc(sizeof(char)*(len + 2));
        c[0] = '('; strcat(c, Ap); strcat(c, Bp); c[len+1] = ')';
        ret->name = (char*)malloc(sizeof(char)*(len + 2));
        strcpy(ret->name, c);
        ret->R = A->R; ret->C = B->C;
        ret->dim = ret->R*ret->C;
        free(Ap); free(Bp); free(c);
}

matrix_list.h

typedef struct node {
        Matrix *M;
        struct node *next;
        struct node *prev;
} Node;

typedef struct matrix_list {
        Node *head;
        Node *tail;
        int size;
        void (*append)( struct matrix_list *list, Matrix *M );
        void (*print)( struct matrix_list *list );
        void (*reverse_print)( struct matrix_list *list );
        void (*delete)( struct matrix_list *list, const char *name );
        void (*delete_tail)( struct matrix_list *list );
        void (*delete_head)( struct matrix_list *list );
        void (*release)( struct matrix_list *list );
        void (*clone_list)( struct matrix_list *from, struct matrix_list *to );
} MatrixList;

...

void clone_list( MatrixList *from, MatrixList *to ) {
        if( from->head == NULL ) {
                to = NULL;
        } else {
                Node *tmp = from->head;
                while( tmp != NULL ) {
                        Matrix *m_copy = (Matrix*)malloc(sizeof(Matrix*));
                        char *c_copy = (char*)malloc(sizeof(char*)*strlen(tmp->M->name));

                        strcpy(c_copy,tmp->M->name);
                        m_copy->name=c_copy;
                        m_copy->R=tmp->M->R;
                        m_copy->C=tmp->M->C;
                        m_copy->concat_matrices = concat_matrices;

                        to->append( to,m_copy );
                        tmp = tmp->next;
                }
        }
}

main.c

chain->print(chain);

MatrixList *chain_copy = (MatrixList*)malloc(sizeof(MatrixList));
set_list_functions( chain_copy );
chain->clone_list(chain, chain_copy);
chain_copy->print(chain_copy);

The problem arises when I try and print out the clone. Because I am malloc’ing in the clone function I understand the data goes out of scope. How can I do this copy so after the function is called clone has its own version of the data?


UPDATE:

First I would like to thank you all for taking your time to answer my question, and for teaching me more about C. I have only been coding for about 3 years. And I have a lot to learn. The updated source with 0 errors from Valgrind can be found at.

http://matthewh.me/Scripts/c++/matrix_chain/ for anyone else trying to figure out things like me. User = guest Password = guest. The clone_list function now looks like this.

void clone_list( MatrixList *from, MatrixList *to ) {
        if( from->head == NULL ) {
                to = NULL;
        } else {
                Node *tmp = from->head;
                while( tmp != NULL ) {
                        Matrix *m_copy = (Matrix*)malloc(sizeof(Matrix));
                        m_copy->name = (char*)malloc(strlen(tmp->M->name) + 1);

                        sprintf( m_copy->name, "%s", tmp->M->name );
                        m_copy->R=tmp->M->R;
                        m_copy->C=tmp->M->C;
                        m_copy->concat_matrices = concat_matrices;

                        to->append( to,m_copy );
                        tmp = tmp->next;
                }
        }
}

If anyone else sees anything else wrong and would like to add additional pointers please feel free to do so.

  • 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-23T15:22:09+00:00Added an answer on May 23, 2026 at 3:22 pm

    You haven’t allowed for the null that terminates strings, so you have classic buffer overflows.

    You also do not need to copy the names three times. Your current code is:

    int L1 = strlen( A->name );
    int L2 = strlen( B->name );
    int len = L1 + L2;
    char *Ap = (char*)malloc(L1*sizeof(char)); strcpy(Ap,A->name);
    char *Bp = (char*)malloc(L2*sizeof(char )); strcpy(Bp,B->name);
    char *c = (char*)malloc(sizeof(char)*(len + 2));
    c[0] = '('; strcat(c, Ap); strcat(c, Bp); c[len+1] = ')';
    ret->name = (char*)malloc(sizeof(char)*(len + 2));
    strcpy(ret->name, c);
    ret->R = A->R; ret->C = B->C;
    ret->dim = ret->R*ret->C;
    free(Ap); free(Bp); free(c);
    

    This should be:

    int   L1 = strlen(A->name);
    int   L2 = strlen(B->name);
    
    ret->name = (char *)malloc(L1 + L2 + sizeof("()"));  // That adds 3
    sprintf(ret->name, "(%s%s)", A->name, B->name);
    
    ret->R   = A->R;
    ret->C   = B->C;
    ret->dim = ret->R * ret->C;
    

    This eliminates Ap, Bp and c altogether, and avoids the buffer overflow problems. I’m not sure I’d slam the two names together like you do, but that’s your choice.


    Apparently, this isn’t sufficient of a problem…there are other issues too.

    void clone_list( MatrixList *from, MatrixList *to ) {
        if (from->head == NULL) {
            to = NULL;
        } else {
            Node *tmp = from->head;
            while( tmp != NULL ) {
                Matrix *m_copy = (Matrix*)malloc(sizeof(Matrix*));
                char *c_copy = (char*)malloc(sizeof(char*)*strlen(tmp->M->name));
    
                strcpy(c_copy,tmp->M->name);
                m_copy->name=c_copy;
                m_copy->R=tmp->M->R;
                m_copy->C=tmp->M->C;
                m_copy->concat_matrices = concat_matrices;
    
                to->append( to,m_copy );
                tmp = tmp->next;
            }
        }
    }
    

    The first assignment zeroes the local pointer; it doesn’t do a thing to the MatrixList passed in as the target. This should presumably be:

    if (from->head == 0)
    {
        *to = *from;
    }
    

    This does a wholesale structure copy, but sets the head and tail to null, and the function pointers are all fine – they can be shared. Assuming that the size in from was correctly zero, it will be correct in to too. (Again, this is probably not the code you are exercising.)

    The next problem is with the memory allocation:

    Matrix *m_copy = (Matrix*)malloc(sizeof(Matrix*));
    

    This allocates one pointer’s worth of memory, not one Matrix’s worth. Use either of these:

    Matrix *m_copy = (Matrix *)malloc(sizeof(*m_copy));
    Matrix *m_copy = (Matrix *)malloc(sizeof(Matrix));
    

    That is a major source of your trouble (and one which valgrind will find easily).


    When the +1 gets forgotten once, it gets forgotten many times, but this time it doesn’t cause problems unless the name is the empty string because you multiply by 4 or 8 (32-bit or 64-bit) because of the sizeof(char *) instead of the intended sizeof(char).

    char *c_copy = (char*)malloc(sizeof(char*)*strlen(tmp->M->name));
    strcpy(c_copy,tmp->M->name);
    

    This should probably be:

    m_copy->name = (char *)malloc(strlen(tmp->M->name) + 1);
    strcpy(m_copy->name, tmp->M->name);
    

    I’d probably use a name like old instead of tmp. I am also remiss in not reminding previously that you should religiously check every return from every memory allocation. Or use a set of cover functions for the memory allocation routines which do the check for you (often called xmalloc() or emalloc(), etc.).

    The code below that does not seem to copy the dim member across, which is a bug if you ever depend on it.

    I’m not entirely happy that you seem to rely on the to list being appropriately initializes before calling clone_list(). In particular, the head, tail and size members are not zeroed here, and the function pointers are not set. I’d be happier to see something like:

    *to = *from;  // Copy function pointers
    to->head = 0;
    to->tail = 0;
    to->size = 0;
    Node *old = from->head;
    for (Node *old = from->head; old != NULL; old = old->next)
    {
        Matrix *m_copy = clone_matrix(old->M);
        to->append(to, m_copy);
    }
    

    Or even:

    matrixlist_initialize(to);
    Node *old = from->head;
    for (Node *old = from->head; old != NULL; old = old->next)
    {
        Matrix *m_copy = clone_matrix(old->M);
        to->append(to, m_copy);
    }
    

    The clone_matrix() function looks like:

    Matrix *clone_matrix(const Matrix *old)
    {
        Matrix *m_copy = (Matrix*)malloc(sizeof(*m_copy));
    
        m_copy->name = (char*)malloc(strlen(old->name)+1);
    
        strcpy(m_copy->name, old->name);
        m_copy->R   = old->R;
        m_copy->C   = old->C;
        m_copy->dim = old->dim;
        m_copy->concat_matrices = concat_matrices;
        return(m_copy);
    }
    

    I downloaded a version your code and it now seems to work, more or less. You should be compiling with at least -Wall as a compiler option; I refuse to compile with anything less and usually use -Wextra too. I make too many simple-to-spot mistakes not to make full use of the compiler, and while you are learning, you will too. (I’ve only been coding in C for just over a quarter century; the compiler still catches typos and other silly mistakes, but I seldom have big problems once the code is compiling.)

    When I turned on -Wall, there was a problem with the (unused) perm() function because it doesn’t return a value even though it says it will, and there was a problem because the correct definition for main() with arguments is int main(int argc, char **argv) and you were missing one of the stars. Other than that, it seems to be working OK now – you can continue with your development.

    There is a function in POSIX called strdup() which duplicates a string reliably. It is useful and avoids the off-by-one mistakes.

    You should review the use of headers. They are for declarations, primarily. If you explicitly use inline (your code doesn’t yet), it can be appropriate to include inline functions in a header, but otherwise, function bodies should not be in headers. They should be in source files (.c suffix). Each header should contain the minimum necessary information for the code that uses the functionality provided by the source to use. It should not include extraneous headers, but it should include all necessary headers. In matrix.h, you include <stdio.h> which is unnecessary. And if you removed the code, neither <string.h> nor <stdlib.h> would be needed either.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm having some issues with my linked list. I have struct dListNode used as
I am having some issues with a small program I have made that edits
I have been having some issues with LINQ-To-SQL around memory usage. I'm using it
I am having some issues involving Parallel for loops and adding to a List.
I'm trying to do my first pyopengl program but having some issues when calling
having some issues with a networking assignment. End goal is to have a C
I'm having some issues simplifying some functions in mathematica. In a program I wrote
I have been having some major issues with my Visual Studio 2008 Pro install.
Hi I'm logging slow queries because we're having some performance issues and I have
Having some issues getting my head around the differences between UTF-8, UTF-16, ASCII and

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.