关闭。这个问题需要更多focused .它目前不接受答案。
想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .
3年前关闭。
Improve this question
我正在研究与动态内存一起使用的指针,我已经完成了一个 MCVE 代码,我在其中创建了一个动态字符串数组(指向 char 的指针的指针),用 malloc 初始化它,分配值,将它发送到一个打印它们的函数并返回确定,然后释放内存(完整代码在帖子的底部。我建议在问题之前查看完整代码)。
这样做,我有疑问:
char **stringArray = NULL;
stringArray = malloc(NUM_OF_ELEMENTS*sizeof(char));
for (i = 0; i < NUM_OF_ELEMENTS; i++)
stringArray[i] = malloc((STRING_LENGTH+1)*sizeof(char));
/*
FIRST: Init a double pointer to char
SECOND: Create number of elements of the array (number of strings)
When is created the number of elements... is not needed end it with '\0' char, right?
When malloc is done... is needed mult it *sizeof(char)? In case it is not like that, is needed mult it *sizeof(anything)?
THIRD: Create length of each string
*/
// Creating elements
// User input
for (i = 0; i < NUM_OF_ELEMENTS-1; i++) {
printf("Input: %i with letters (One, Two,..): ", i+1);
gets(userInput);
strcpy(stringArray[i], userInput); // stringArray[0] = "One"; stringArray[1] = "Two"
}
// Manually
strcpy(stringArray[NUM_OF_ELEMENTS-1], "Three"); // stringArray[2] = "Three"
char *functionWhichReturnsOneString() {
return "string";
}
printElementsOfStringArrayPassedByValue(stringArray) // Call to function
char *printElementsOfStringArrayPassedByValue(char **stringArray) {
int i = 0;
for (i = 0; i < NUM_OF_ELEMENTS; i++)
printf("%s\n", stringArray[i]);
return "OK";
}
printElementsOfStringArray2PassedByReference(&stringArray) // Call to function
char *printElementsOfStringArray2PassedByReference(char ***stringArray) {
int i = 0;
for (i = 0; i < NUM_OF_ELEMENTS; i++)
printf("%s\n", (*stringArray)[i]); // Is it equal to: *((*stringArray)+i) ?
return "OK";
}
(*stringArray)[i])
和:*((*stringArray)+i)
, 对? 完整代码为:
#include <stdio.h>
#include <string.h>
#define NUM_OF_ELEMENTS 3
#define STRING_LENGTH 35
char *printElementsOfStringArrayPassedByValue(char **stringArray) {
int i = 0;
for (i = 0; i < NUM_OF_ELEMENTS; i++)
printf("%s\n", stringArray[i]);
return "OK";
}
char *printElementsOfStringArray2PassedByReference(char ***stringArray) {
int i = 0;
for (i = 0; i < NUM_OF_ELEMENTS; i++)
printf("%s\n", (*stringArray)[i]); // Is it equal to: *((*stringArray)+i) ?
return "OK";
}
int main(void) {
// Variables
int i = 0;
char userInput[STRING_LENGTH] = {'\0'};
char **stringArray = NULL;
char returnedValue[STRING_LENGTH] = {'\0'};
// Creating array of strings
stringArray = malloc(NUM_OF_ELEMENTS*sizeof(char)); // Here is correct: *sizeof(char)?; Is not needed \0 char?
// Creating each element of the array
for (i = 0; i < NUM_OF_ELEMENTS; i++)
stringArray[i] = malloc((STRING_LENGTH+1)*sizeof(char));
// Creating elements
// User input
for (i = 0; i < NUM_OF_ELEMENTS-1; i++) {
printf("Input: %i with letters (One, Two,..): ", i+1);
gets(userInput);
strcpy(stringArray[i], userInput); // stringArray[0] = "One"; stringArray[1] = "Two"
}
// Manually
strcpy(stringArray[NUM_OF_ELEMENTS-1], "Three"); // stringArray[2] = "Three"
strcpy(returnedValue, printElementsOfStringArrayPassedByValue(stringArray)); // Pass by value and return a string
printf("%s - Ended print 1\n", returnedValue);
strcpy(returnedValue, printElementsOfStringArray2PassedByReference(&stringArray)); // Pass by reference and return a string
printf("%s - Ended print 2\n", returnedValue);
// Freeing memory
for (i = 0; i < NUM_OF_ELEMENTS; i++) {
free(stringArray[i]);
stringArray[i] = NULL;
}
free(stringArray);
stringArray = NULL;
return 0;
}
谢谢你的帮助。
最佳答案
- 该方法没问题,但第一个 sizeof 参数是错误的(stringArray 的类型为 char**,而不是 char*),最好将 sizeof 与 malloc 一起使用,如下所示:
char **stringArray = NULL;
stringArray = malloc(NUM_OF_ELEMENTS * sizeof(*stringArray));
for (i = 0; i < NUM_OF_ELEMENTS; i++)
stringArray[i] = malloc((STRING_LENGTH+1) * sizeof(*stringArray[i]));
而对于编程高手,最好使用 calloc 来处理整数溢出:
char **stringArray = NULL;
stringArray = calloc(NUM_OF_ELEMENTS, sizeof(*stringArray));
assert(stringArray != NULL);
for (i = 0; i < NUM_OF_ELEMENTS; i++) {
stringArray[i] = calloc(STRING_LENGTH+1, sizeof(*stringArray[i]));
assert(stringArray[i] != NULL);
}
- 是的,不要使用
gets
.删除 gets
从内存里。使用 fgets(userInput, sizeof(userInput), stdin);
- 您必须确保字符串的存储持续时间比函数长。在您的示例中,您返回一个指向 string literal 的指针。 .并且字符串文字具有静态存储持续时间,就像您在文件范围内声明它一样,所以在这里很好。如果你要返回一个指向 compound literals 的指针或者你会在堆栈上初始化字符串,这将是一个问题。这样的函数将返回一个指向字符串的指针,但是一旦函数退出,您不知道该字符串是否存在,因为该字符串在函数返回后不再存在。你也可以:
static char *string_to_return = "string";
char *functionWhichReturnsOneString_global() {
return string_to_return;
}
char *functionWhichReturnsOneString_static() {
static char *string_to_return_2 = "string";
return string_to_return;
}
这样 string_to_return 具有静态存储持续时间,它将在全局范围内可用。另一种方法是使用 malloc(或 strdup)为字符串分配内存并返回指向该内存的指针(记住之后释放它(!)):
char *functionWhichReturnsOneString_malloc() {
char *string_to_return = malloc(sizeof("string"));
memcpy(string_to_return, "string", sizeof("string"));
return string_to_return;
}
char *functionWhichReturnsOneString_strdup() {
return strdup("string");
}
- 功能完全相同。 stringArray 是指向字符数组的指针数组。它是一个指针,指向一个指针数组,每个指针指向一个字符数组。将 stringArray 传递给函数足以修改存储在数组中的字符(作为 stringArray 指向这些数组),例如。调整这些数组的大小。如果您传递 &stringArray,您的函数可能会更改数组的数量(即 NUM_OF_ELEMENTS)(不是特定数组中的字符数,而是数组本身的数量)。你可以做
*stringArray = realloc(*stringArray, (NUM_OF_ELEMENTS+20)*sizeof(**stringArray));
- 是的。表达式 A[B]
等于 B[A]
等于 *(B+A)
.搞笑,这也等于:*i[*stringArray]
,但这种形式伤害了我的眼睛。
关于字符指针 : Creating dynamic string array, 赋值并传递给其他函数和其他小家伙 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49721815/