The problem here is with

 char Tmp[]="";

here, Tmp is not an dynamic array, it's an array with exactly one element (initialized via the initializer). When you use this as destination for strcpy(), you're overrunning the buffer. Basically, your code tries to access out of bound memory, which invokes undefined behavior.

Related, quoting C11, chapter §7.24.2.3, strcpy(), emphasis mine

The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1. [...]

and then, for "String function conventions", §7.24.1,

[....] If an array is accessed beyond the end of an object, the behavior is undefined.

Solution: You need to ensure that Tmp has enough memory to hold the content to be copied into it, including the null terminator.

That said, for a hosted environment, int main() should at least be int main(void) to be conforming to the standard.

Answer from Sourav Ghosh on Stack Overflow
🌐
D Programming Language Discussion Forum
forum.dlang.org › thread › heqttlktcipflzqrpbed@forum.dlang.org
Using "strcpy" to assign value to dynamic char array - D Programming Language Discussion Forum
I know that I can use the next syntax to assign new value to char dynamic array, and the new value isn't in same length of the current value of the array: · s="Hello World!".dup;
Discussions

c++ - Use Strcpy_s to Copy Dynamically Allocated Char Array - Stack Overflow
I'm simply trying to copy what is in 'temp' into 'p' but the program crashes on the strcopy_s line. Am I missing some important rule? #include #include #include More on stackoverflow.com
🌐 stackoverflow.com
c - Strcpy a static char array into a dynamically allocated char array to save memory - Stack Overflow
Say, in main(); you read a string from a file, and scan it into a statically declared char array. You then create a dynamically allocated char array with with length strlen(string). Ex: FILE *ifp; ... More on stackoverflow.com
🌐 stackoverflow.com
Using strcpy with a string array in C - Stack Overflow
The char *c[20] definition is incorrect because you are just defining an array of 20 pointers, and the pointers are not initialized. You could make it work in this way: char *c[20]; for (int k = 0; k < 20; k++) { c[k] = malloc(70); strcpy(c[k], "undefined"); } // then when you are done with ... More on stackoverflow.com
🌐 stackoverflow.com
c++ - strcpy function with dynamic allocated char array - Stack Overflow
Edit: As answered by Igor Tandetnik and user17732522 in the comments and Joseph Larson in the reply below, this was solved by adding the buffer argument to the strcpy_s function, making it a total of 3 arguments. ... How do I copy that string into the char array? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Dynamic memory with strcmp/strcpy - Programming - Arduino Forum
December 24, 2015 - Hi, I'm having some problems managing the dynamic memory in my code. Assume that I'm already allocating 22% of dynamic memory (according to the IDE). So I'm using an array of char arrays, and I want to use strcmp or strcpy, for example: const char names[25][24] if (strcmp(strtocompare, names[0]) == 0){ Serial.println(F("hehe")); } My dynamic memory allocation jumps up to 52%, and I have no idea why.
🌐
Diveintosystems
diveintosystems.org › book › C2-C_depth › strings.html
2.6.1. C's Support for Statically Allocated Strings (Arrays ...
When dynamically allocating space to store a string, it’s important to remember to allocate space in the array for the terminating '\0' character at the end of the string. The following example program demonstrates static and dynamically allocated strings (note the value passed to malloc): #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int size; char str[64]; // statically allocated char *new_str = NULL; // for dynamically allocated strcpy(str, "Hello"); size = strlen(str); // returns 5 new_str = malloc(sizeof(char) * (size+1)); // need space for '\0' if(new_str == NULL) { printf("Error: malloc failed!
Find elsewhere
🌐
Digitalmars
digitalmars.com › d › archives › digitalmars › D › learn › Using_strcpy_to_assign_value_to_dynamic_char_array_126270.html
digitalmars.D.learn - Using "strcpy" to assign value to dynamic char array
November 1, 2021 - I know that I can use the next syntax to assign new value to char dynamic array, and the new value isn't in same length of the current value of the array: { char[] s="xyz".dup; s="Hello World!".dup; writeln(s); } Result: Hello World! ===================== But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { char[] s="xyz".dup; strcpy(&s[0], "Hello World!"); writeln(s); } Result: Hel
Top answer
1 of 1
1

There are a few things I find troublesome. First, you've seen people say you should use std::string instead of char arrays, and that's true. But new programmers should understand the entire language, and so understanding how to use char arrays has value.

So let's ignore C++ strings and look at your code:

char ** test = createCharArray(); // array of pointers to char arrays
char *asd = new char[MAXSIZE];
cin >> asd;

for (int i = 0; i < PARAM_COUNT; ++i) {
    strcpy_s(test[i], asd);
}

for (int i = 0; i < PARAM_COUNT; ++i) {
    cout << i << " " << test[i] << endl;
}

deleteCharArray(test);
return 0;

Let's start with this. We don't know what createCharArray() does. Is it doing everything it should? Not only should it create an array of char pointers, but the way you're using it, it also needs to create the buffers they each point to. So it might look something like this:

char ** createCharArray() {
   char ** array = new char *[PARAM_COUNT];
   for (int index = 0; index < PARAM_COUNT; ++index) {
        array[index] = new char[MAXSIZE];
   }
   return array;
}

If yours looks remarkably different, you may have issues.

After that, let's look at this:

for (int i = 0; i < PARAM_COUNT; ++i) {
    strcpy_s(test[i], asd);
}

As others have said, this version of strcpy_s takes three arguments: strcpy_s(test[i], asd, MAXSIZE);

Note that you're copying the same string into place multiple times. I wonder if your code should really do this:

for (int i = 0; i < PARAM_COUNT; ++i) {
    cin >> asd;
    strcpy_s(test[i], asd, MAXSIZE);
}

And finally, the delete method needs to delete the individual pointers and then the array of pointers.

🌐
Ubaldo Acosta Soto
ictdemy.com › c-language › dynamic-memory-allocation › dynamic-strings-and-structures-in-the-c-language
Lesson 4 - Dynamic strings and structures in the C language
This auxiliary array is often called a buffer. Let's show code and explain it: char buffer[101]; printf("Enter your name: "); // Stores the name into auxiliary memory scanf(" 0[^\n]", buffer); // Creates a dynamic string char* name = (char *) malloc(strlen(buffer) + 1); // Sets the value strcpy(name, buffer); printf("Your name is %s", name); // Frees the memory free(name);
🌐
cppreference.com
en.cppreference.com › c › string › byte › strcpy
strcpy, strcpy_s - cppreference.com
strcpy_s is allowed to clobber the destination array from the last character written up to destsz in order to improve efficiency: it may copy in multibyte blocks and then check for null bytes.
🌐
Bytes
bytes.com › home › forum › topic
Replacing 'strcpy' with 'strcpy_s' for dynamic string - Post.Byes
March 13, 2007 - No, in fact you will never be able to get a function like this working for a dynamically allocated string without passing the size of the string because all the code has to go on is the type of a the variable and for a dynamically allocated string that is a pointer. strcpy is not deprecated, Microsoft say so but they do not write the C/C++ standards, on some *nix platforms strcpy is replaced by strlcpy.
🌐
DaniWeb
daniweb.com › programming › software-development › threads › 416142 › dynamic-array-size
encryption - Dynamic array size [SOLVED] | DaniWeb
You can, if you want to, declare it like this: char str[80] = "Hello"; In that case the compiler will allocate 80 bytes of memory, initializing the first few bytes with the string. The second method is best if you know that str may eventually contain more characters, such as if you want to call strcat() to add additional characters or strcpy() to completely overwrite the existing string with something else.
Top answer
1 of 1
4
  • Well clearly the error is using strcpy wrongly.

    The correct way would be

    strcpy(firstNames[set], firstName);
    
  • Also in the loop it should be

        for (cset = 0; cset < MAX_COURSES; cset++)
        {
            strcpy(courses[cset], dynCourses);
            strcpy(grades[cset], dynGrades);
        }
    

    Note that the idiomatic C loop is for (int i = 0; i < MAX; i++), using < and not <=.

The signature of the strcpy function is

 char *strcpy(char * restrict s1, const char * restrict s2);

Earlier you passed in place of s1 a char instead of char*. You must have got some warning (if enabled). If not then turn all compiler flags -Wall -Werror.

             if (firstNames[set][cset] == '\0')

But if you are initially checking an uninitilized value with \0. This will higly unlikely will turn out to be false. There is no gurantee that the char array which doesn't contain strings will be initialized with 0 automatically. So make sure you have initialized the char arrays in the callee function like this

char arr[20][50]={0};
  • The loop is from 0 to MAX_STUDENTS. You are invoking an undefined behavior looping on array index out of bound if MAX_STUDENTS is greater than or equal to 50. Same goes for MAX_COURSES. More clearly the looping would be for (set = 0; set < (50); set++).

  • Again there will be a lot better way to deal with it if you put the initialization and copy part seperate. Otherwise this will be uneasy to maintain.

  • Seeing your use courses it is obvious that you want to declare it like this

    char courses[5][20];
    

same goes for the grades array. Here you were trying to copy a string into into a 2d array. Compiler would complain about type incompatibility.

  • Also in the function you didn't return anything meaningful. The correct way would be to return the index value on which new name or information is added.

  • Here you are copying content of dynGrades and dynCourses to the array. So they will all contain the same values. Is this what you want? Because then what's the use of keeping 5 seperate char arrays - one could serve the purpose pretty well.

🌐
Stack Overflow
stackoverflow.com › questions › 35931865 › writing-strings-to-dynamically-allocated-array
c - Writing strings to dynamically allocated array - Stack Overflow
June 3, 2016 - so that you can copy the string to that dynamic array. ... Suppose arr[counter] holds the address of a char pointer which is 1000. So strcpy(arr[counter][index],token); will copy the string in the address 1000 + index.
🌐
Stack Overflow
stackoverflow.com › questions › 55875518 › creating-a-dynamic-char-array
c - Creating a dynamic char array - Stack Overflow
char ** array; int main(int argc, char * argv[]){ int size = 0; int i; FILE * file; char * line; size_t len; ssize_t read; file = fopen("wordsEn.txt", "r"); if(file == NULL){ printf("Error coudl not open wordsEn.txt\n"); return -1; } while((read = getline(&line, &len, file)) != -1){ size++; } array = (char **) malloc((sizeof(char *) * size)); rewind(file); i = 0; while((read = getline(&line, &len, file)) != -1){ //strcpy(array[i], line); array[i] = strdup(line); i++; } for(i = 0; i < size; i++){ printf("%s", array[i]); } } I am expecting for example array[0] to return the string 'alphabet' ... store the words into a dynamic char array – What does that mean?
🌐
RIT
se.rit.edu › ~swen-250 › slides › instructor-specific › Rabb › C › 06-C-Memory-Alloc-Strings.pdf pdf
Personal Software Engineering Memory Management in C (Dynamic Strings)
strcpy(copy, orig) ; return copy ; } Examples: Make a Copy of a String · #include <stdlib.h> #include <string.h> /* * Return a copy of an existing NUL-terminated string. */ char *make_copy(char *orig) { char *copy ; copy = malloc(strlen(orig) + 1) ; strcpy(copy, orig) ; return copy ; } Uninitialized pointer - until ·
Top answer
1 of 2
6

If you ever find yourself attempting to use sizeof() for anything that is sized dynamically, you're doing it wrong. Keep that in mind. sizeof() is used repeatedly in this code incorrectly. Dynamic size counts must be managed by you; the allocation size requirements in bytes can be managed using those counts in conjunction with a sizeof() of the fundamental type for the item being stored.

Given that:

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

int main(int argc, char *argv[])
{
    int i = 0;
    int arrayIndexes = 2;
    char ** myArray = malloc(arrayIndexes * sizeof(*myArray));

    //Allocate memory for each [x]
    for (i = 0; i < arrayIndexes; i++)
    {
        myArray[i] = malloc(254 * sizeof(char));
        sprintf(myArray[i], "string %d", i+1);
    }

    //Print out array values
    printf("Before: \n");
    for (i = 0; i < arrayIndexes; i++)
        printf("Array[%d]: %s\n", i, myArray[i]);

    // TODO: Fix this to check the result before orphaning the old
    //  value of myArray if an allocation failure ensues.
    myArray = realloc(myArray, (arrayIndexes+1) * sizeof(*myArray));
    ++arrayIndexes;

    //Allocate memory for the new string item in the array
    myArray[arrayIndexes-1] = malloc(254 * sizeof(char*));

    //Populate a new value in the array
    strcpy(myArray[arrayIndexes-1], "string 3"); //

    //Print out array values
    printf("After: \n");
    for (i = 0; i < arrayIndexes; i++)
        printf("Array[%d]: %s\n",i, myArray[i]);

    // TODO: write proper cleanup code just for good habits.
    return 0;
}

Output

Before: 
Array[0]: string 1
Array[1]: string 2
After: 
Array[0]: string 1
Array[1]: string 2
Array[2]: string 3
2 of 2
2

You shall replace this line:

arrayIndexs = sizeof(*myArray)/sizeof(char*);

by something like this:

arrayIndexs += 1;

Reason: sizeof is a compile-time operator to determine the size of a datatype or datatype of an object, while here you shall manually maintain the array size.

EDTIED: Also when initializing the variable, you shall use

int arrayIndexs = 2;

instead of

int arrayIndexs = sizeof(*myArray) / sizeof(char*);