所以,我面臨一個我不太了解的問題。請善待我正在嘗試自己學習C!
我有一個名為secureInput()的函式,它接受一個指向字串的指標和一個大小,這樣,當用戶必須鍵入一些輸入時,我可以確保沒有緩沖區溢位。現在,問題是我想修改字串而不復制它,而是直接通過它的記憶體地址修改它,但是當分配用戶輸入中的第二個字符時它會崩潰。查看評論以查看它在哪里崩潰。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int secureInput(char **str, int size);
int main(int argc, const char * argv[]) {
char *mystring = NULL; // Declaring it a null so that I use malloc later
secureInput(&mystring, 10);
printf("%s\n", mystring);
}
int secureInput(char **str, int size)
{
*str = (char*)malloc(sizeof(char) *size); // Because **str is a null pointer, I use malloc to allocate memory.
if (*str == NULL)
return -1;
int c = 0;
unsigned int count = 0;
while((c = getchar()) != '\n' && count < size)
/* Here is where it crashes.
* But changing the bellow line as : *str[0][count ] = c;
* works as expected. Also, using a temporary pointer
* and later using it to replace *str, is also working
*/
*str[count ] = c;
*str[count] = '\0';
return 0;
}
uj5u.com熱心網友回復:
所以首先,您可以將字串作為 a 傳遞char*,不需要char**. 當作為引數傳遞時,它通常用于字串陣列。然后,如果您想使用一個固定大小的陣列,一個具有常量、預定義大小的緩沖區,請不要使用 malloc。動態記憶體分配總是低效且有風險的,因此只有在絕對必要時才使用它。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define BUFFER_SIZE 10
int secureInput(char *str, int size);
int main(int argc, const char * argv[]) {
char mystring[BUFFER_SIZE]; // Declaring it a null so that I use malloc later
memset(mystring, 0, BUFFER_SIZE);
secureInput(mystring, BUFFER_SIZE);
printf("%s\n", mystring);
}
int secureInput(char *str, int size) {
char c = 0;
unsigned int count = 0;
c = getchar();
while(c != '\n' && count < size - 1) {
str[count ] = c;
c = getchar();
}
str[count] = '\0';
return 0;
}
編輯:
我可以看到關于指標演算法仍然存在一些混淆。這是一些地址列印和一個小圖,希望對您有所幫助:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int secureInput(char **str, int size);
int main(int argc, const char * argv[]) {
char *mystring = NULL; // Declaring it a null so that I use malloc later
secureInput(&mystring, 10);
}
int secureInput(char **str, int size) {
*str = (char*)malloc(sizeof(char) *size); // Because **str is a null pointer, I use malloc to allocate memory.
(*str)[0] = 'a';
(*str)[1] = 'b';
(*str)[2] = 'c';
(*str)[3] = 0;
printf("address of the pointer that points to a pointer that points the first char of the array : %p\n", &str);
printf("value of the pointer that points to a pointer that points to the first char of the array : %p\n", str);
printf("address of the pointer that points to the first char of the array : %p\n", &(*str));
printf("value of the pointer that points to the first char of the array : %p\n", *str);
printf("address of the first char of the array: %p\n", &(**str));
printf("address of the seconds char of the array: %p\n", &((*str)[1]));
printf("value of the first char of the array : %c\n", **str);
printf("value of the second char of the array : %c\n", *(*str 1));
printf("value of the second char of the array : %c\n", (*str)[1]);
printf("*str[1] is the same as *(str[1]), which runs to a segmentation fault\n");
return 0;
}
輸出:
address of the pointer that points to a pointer that points the first char of the array : 0x7ffce24333f8
value of the pointer that points to a pointer that points to the first char of the array : 0x7ffce2433430
address of the pointer that points to the first char of the array : 0x7ffce2433430
value of the pointer that points to the first char of the array : 0x55a91985a2a0
address of the first char of the array: 0x55a91985a2a0
address of the seconds char of the array: 0x55a91985a2a1
value of the first char of the array : a
value of the second char of the array : b
value of the second char of the array : b
*str[1] is the same as *(str[1]), which runs to a segmentation fault
0x7ffce24333f8 0x7ffce2433430
---------------- ---------------- ----------------
| 0x7ffce2433430 | -------> | 0x55a91985a2a0 | -------> | a | 0x55a91985a2a0
---------------- ---------------- ----------------
----------------
| b | 0x55a91985a2a1
----------------
----------------
| c | 0x55a91985a2a2
----------------
關鍵是您取消參考哪個指標很重要。
uj5u.com熱心網友回復:
至少這個問題:
一關
str[count] = '\0';可以在陣列邊界之外寫入導致 OP 的麻煩。建議count < size--> count 1 < size.
并非總是閱讀整行
讀取部分行會導致麻煩。
如何讀取整行并報告結果?讓呼叫代碼提供固定大小的緩沖區。
區分讀取空行和檔案尾。
size == 0優雅地處理。
// EOF: end-of-file with no input
// EOF: input error
// 0: input, but too much
// 1: Success
int secureInput(char *str, size_t size) {
if (str == NULL) {
size = 0;
}
bool too_many = false;
size_t count = 0;
int c;
while((c = getchar()) != '\n') {
if (c == EOF) {
if (feof(stdin) && count > 0) {
break;
}
if (size > 0) {
str[0] = '\0';
}
return EOF;
}
if (count 1 < size) {
str[count ] = c;
} else {
too_many = true;
}
}
if (count < size) {
str[count] = '\0';
}
return count < size && !too_many;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/322587.html
上一篇:分段默認值(雙指標/結構)
下一篇:C中N個自然數的總和
