简体   繁体   English

对指针感到困惑?

[英]Confused about pointers?

I'm trying to write a response into a variable, and I can't figure out how to do it. 我正在尝试将响应写入变量,但我不知道该怎么做。

This doesn't work - screws up memory, but no protection errors: 这不起作用-破坏内存,但没有保护错误:

for (int i = 0; i < 20; i++) {
    list[i] = 'a';
}

Same with this - memory screwed up: 与此相同-内存损坏了:

for (int i = 0; i < 20; i++) {
    *(((int*)(list))+i) = 'a';
}
//I don't think this is a string issues as this doesn't help:
//*(((int*)(list))+20) = '\0';

This causes a bus error: 这会导致总线错误:

for (int i = 0; i < 20; i++) {
    *list[i] = 'a';
}

This works as desired: 这可以按需工作:

*list = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

What am I doing wrong? 我究竟做错了什么?

PS list is char** . PS listchar**

In C, a pointer can be used to represent an array, and a single string is an array of char , or in other words, a char * . 在C语言中,可以使用指针来表示数组,并且单个字符串是char的数组,换句话说,就是char * This means that a char ** is an array of strings. 这意味着char **是字符串数组。 So if you want to put characters into the first string (assuming that memory has already been allocated to it), you should use list[0][i] = 'a'; 因此,如果要在第一个字符串中放入字符(假设已经为它分配了内存),则应使用list[0][i] = 'a'; in the first loop - ie, put 'a' into position i of the 0 th string. 在第一个循环中-即,将'a'放入第0个字符串的位置i

Another way of interpreting a char ** (which is the one I suspect is the one you're supposed to use) is that it is a pointer that points to a pointer that points to an array of char . 解释char **另一种方式(我怀疑这是您应该使用的一种),它是一个指向指向char数组的指针的指针。 In that case, you can use the "outer" pointer to modify what the inner pointer points to; 在这种情况下,可以使用“外部”指针修改内部指针指向的内容; this can be used to first allocate the string and then write to it: 这可以用来首先分配字符串,然后写入它:

*list = malloc(21); // Allocate 21 bytes and make the pointer that 'list' points to refer to that memory
for (int i = 0; i < 20; i++) {
    (*list)[i] = 'a';
}
(*list)[20] = '\0'; // Also, you need the null terminator at the end of the string

In memory, this looks like this: 在内存中,如下所示:

list ---> (another pointer) ---> |a|a|a|a|a|a|...|a|a|\0|

Since you want an array of bytes then char** is wrong – that's a pointer to a pointer to char . 由于您需要一个字节数组,因此char**是错误的–这是指向char指针的指针。 You want char* for an array, but if it's fixed length I'd declare it as char list[20] . 您希望将char*用于数组,但是如果它是固定长度,则将其声明为char list[20]

It seems like you want to write something like this: 似乎您想写这样的东西:

char list[20];
for (int i = 0; i < 20; i++) {
    list[i] = 'a';
}

Or if you want heap allocation use 或者如果您想使用堆分配

char *list = malloc(20);

Since we are reduced to guessing, I think that you meant to say that *list is an array of bytes. 由于我们只能进行猜测,所以我认为您的意思是说*list是字节数组。 In which case the code would be like so: 在这种情况下,代码将如下所示:

char **list = get_list_from_somewhere();
*list = malloc(20);
for (int i = 0; i < 20; i++) {
    *list[i] = 'a';
}
char** list

Isn't a 'array of bytes' its a 'pointer to a pointer pointing to char' which you can think of as a 'list of lists of char'. 不是“字节数组”,而是“指向char的指针的指针”,您可以将其视为“ char的列表列表”。 Also if you define it this way, you need to malloc enough memory to hold the data. 同样,如果以这种方式定义它,则需要malloc足够的内存来保存数据。

When you write: 当你写:

list[i] = 'a';

Its messing up memory because your placing a char 'a' in a location specified to hold a pointer. 它弄乱了内存,因为您将char'a'放置在指定用于保存指针的位置。 Actually in most compilers character literals are of type int so your actually storing an int form of 'a' as a pointer to a memory location which can cause all sorts of memory corruption. 实际上,在大多数编译器中,字符文字是int类型的,因此您实际上存储了一个int形式的“ a”作为指向内存位置的指针,这可能导致各种内存损坏。

If you want 'list' to be on the stack then define it as: 如果您希望“列表”位于堆栈中,则将其定义为:

char list[20]

If you want 'list' to be in the heap then define it as: 如果您希望“列表”位于堆中,则将其定义为:

char* list;
list = malloc(sizeof(char) * 20);

In either case access it as: 无论哪种情况,都可以通过以下方式访问它:

list[i]

Also its not safe to assume the size of int being equivalent to the size of a pointer as you to have done in your second example. 同样假设第二个例子中int的大小等于指针的大小也是不安全的。 At least i think thats what you were trying to do. 至少我认为这就是您想要做的。

Additionally if your storing raw bytes from a data stream or something of that sort you should likely be using 'unsigned char' not 'char' and for more safety use 'int8_t' as you can't always guarantee that 'char' is 8 bits although it is on the majority of platforms. 此外,如果您存储数据流中的原始字节或此类数据,则可能应该使用“无符号字符”而不是“字符”,并且出于安全考虑,请使用“ int8_t”,因为您无法始终保证“字符”为8位尽管它在大多数平台上。

How did you initialize your list ? 您是如何初始化list

char** list;

doesn't work in this case you'll have to have something like 在这种情况下不起作用,您必须拥有类似

char* list[20];

or dynamically allocated. 或动态分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM