多个间接混乱...... [英] Multiple indirection mess-up...

查看:71
本文介绍了多个间接混乱......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


在下面的程序中,我分配一个指针块来键入char,

初始化为零。然后我将每个指针指向一个固定大小(33字节)的分配内存的块。然后使用itoa()和rand()为每个内存块生成一个唯一的''字符串''




最后使用指针指向char类型的指针,我打印内存块的内容,即字符串,使用printf()和

手动逐字符打印。


当尝试逐字符打印时,程序终止

为GPF。我怀疑这个错误是在

第61和74行之间的指针操作。


有人能找到确切的错误吗?


代码如下:

1:/ *文件:006.c * /

2:#include< stdio.h>

3:#include< stdlib.h>

4:#include< time.h>

5:

6 :#define DEF_ALLOC_ITEMS 32

7:#define DEF_STR_SIZE 33 / *因为itoa()最多可以返回33个字节

* /

8:

9:int main(无效)

10:{

11:char ** mptr = NULL;

12:char ** ptr = NULL;

13:char ** sptr = NULL;

14:int rnd;

15: size_t nitems = DEF_ALLOC_ITEMS;

16:size_t ctr;

17:

18:/ *分配一个指向char类型的指针数组为NULL * /

19:mptr = calloc(nitems,sizeof(char *));

20:if(mptr == NULL)

21:退出(EXIT_FAILURE);

22:否则

23:ptr = mptr;

24:

25:/ *种子伪随机数生成器* /

26:srand((无符号)时间( NULL));

27:

28:/ *使用itoa()和rand()作为参数来获取字符串。

29:*将每个分配的指针初始化为一块

30:*已分配,为零的内存,并将其传递给itoa()。

31 :*因此我们得到一个指向char类型的指针块,每个指向

32:*一块大小为DEF_STR_SIZE的内存块,包含字符

33:* string伪随机数的表示。

34:* /

35:nitems = DEF_STR_SIZE;

36:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)

37:{

38:* ptr = calloc(nitems,sizeof(char));

39:if(* ptr == NULL)

40:退出(EXIT_FAILURE);

41:否则

42:{

43 :rnd = rand();

44:printf(字符串%u的\ n生成随机数:%d,

45:ctr + 1, rnd);

46:itoa(rnd,* ptr,10);

47:}

48:ptr ++;

49:}

50:

51:/ *现在打印字符串* /

52:ptr = mptr;

53:puts(" \\\
Printing strings via printf():");

54:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)

55:{

56:printf(" \ nString%u is:%s",ctr + 1,* ptr);

57:ptr ++;

58:}

59:

60:/ *现在使用多个间接手动打印字符串... * /

61:ptr = mptr;

62:sptr = ptr;

63:puts(" \ n\\\
Printing字符串手动使用多个间接:);

64:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)

65:{

66:printf(" \ nString%u is:",ctr + 1);

67:sptr = ptr;

68:while(** sptr!=''\''')

69:{

70:printf("%c",** sptr);

71:* sptr ++;

72:}

73:ptr ++ ;

74:}

75:

76:返回0;

77:}


谢谢。

Hi all,

In the following program I allocate a block of pointers to type char,
initialised to zero. I then point each of those pointers to a block of
allocated memory of fixed size (33 bytes). A unique ''string'' is then
generated using itoa() and rand() for each block of memory.

Finally using pointer-to-pointer of type char, I print the contents of
the blocks of memory, i.e. the strings, using both printf() and
manually, character by character.

When trying to print character by character, the program is terminated
for a GPF. I suspect the fault is in the pointer manipulations between
lines 61 and 74.

Can anyone find the exact mistake?

The code follows:
1: /* File: 006.c */
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <time.h>
5:
6: #define DEF_ALLOC_ITEMS 32
7: #define DEF_STR_SIZE 33 /* Because itoa() can return upto 33 bytes
*/
8:
9: int main( void )
10: {
11: char **mptr = NULL;
12: char **ptr = NULL;
13: char **sptr = NULL;
14: int rnd;
15: size_t nitems = DEF_ALLOC_ITEMS;
16: size_t ctr;
17:
18: /* Allocate an array of pointers to type char, set to NULL */
19: mptr = calloc(nitems, sizeof (char *));
20: if(mptr == NULL)
21: exit(EXIT_FAILURE);
22: else
23: ptr = mptr;
24:
25: /* Seed the pseudo-random number generator */
26: srand((unsigned) time(NULL));
27:
28: /* Use itoa() with rand() as parameter to get a character string.
29: * Initialise each of the allocated pointers to a block of
30: * allocated, zero''ed out memory, and pass it to itoa().
31: * Thus we get a block of pointers to type char, each pointing to
32: * a block of memory of size DEF_STR_SIZE, containing the character
33: * string representation of a pseudo-random number.
34: */
35: nitems = DEF_STR_SIZE;
36: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
37: {
38: *ptr = calloc(nitems, sizeof (char));
39: if(*ptr == NULL)
40: exit(EXIT_FAILURE);
41: else
42: {
43: rnd = rand();
44: printf("\nGenerated random number for string %u is: %d",
45: ctr+1, rnd);
46: itoa(rnd, *ptr, 10);
47: }
48: ptr++;
49: }
50:
51: /* Now print the strings */
52: ptr = mptr;
53: puts("\nPrinting strings via printf():");
54: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
55: {
56: printf("\nString %u is: %s", ctr+1, *ptr);
57: ptr++;
58: }
59:
60: /* Now print the strings manually using multiple-indirection... */
61: ptr = mptr;
62: sptr = ptr;
63: puts("\n\nPrinting strings manually using multiple-indirection:");
64: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
65: {
66: printf("\nString %u is: ", ctr+1);
67: sptr = ptr;
68: while(**sptr != ''\0'')
69: {
70: printf("%c", **sptr);
71: *sptr++;
72: }
73: ptr++;
74: }
75:
76: return 0;
77: }

Thanks.

推荐答案

santosh写道:
santosh wrote:
[... ]
当尝试逐个字符打印时,程序将终止为GPF。我怀疑错误是在第61和第74行之间的指针操作中。

任何人都可以找到确切的错误吗?
[...]
11:char ** mptr = NULL;
12:char ** ptr = NULL;
13:char ** sptr = NULL;
[...]
60 :/ *现在使用多个间接手动打印字符串... * /
61:ptr = mptr;
62:sptr = ptr;
63:puts(" \ n \ n使用多个间接手动打印字符串:");
64:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)
65:{
66:printf(" \ nString%u是:",ctr + 1);
67:sptr = ptr;
68:while(** sptr!=''\''')
69:{
70:printf("%c",** sptr);
71:* sptr ++;


这条线不做你想象的那样。

72:}
73:ptr ++;
74: }
[...]
When trying to print character by character, the program is terminated
for a GPF. I suspect the fault is in the pointer manipulations between
lines 61 and 74.

Can anyone find the exact mistake?
[...]

11: char **mptr = NULL;
12: char **ptr = NULL;
13: char **sptr = NULL;
[...]
60: /* Now print the strings manually using multiple-indirection... */
61: ptr = mptr;
62: sptr = ptr;
63: puts("\n\nPrinting strings manually using multiple-indirection:");
64: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
65: {
66: printf("\nString %u is: ", ctr+1);
67: sptr = ptr;
68: while(**sptr != ''\0'')
69: {
70: printf("%c", **sptr);
71: *sptr++;
This line doesn''t do what you think it does.
72: }
73: ptr++;
74: }




-

Eric Sosman
es ***** @ acm-dot-org.inva lid



--
Eric Sosman
es*****@acm-dot-org.invalid


santosh写道:
santosh wrote:
大家好,

在下面的程序中,我分配一个指针块来键入char,
初始化为零。然后我将每个指针指向一块分配固定大小(33字节)的内存。然后使用itoa()和rand()为每个内存块生成一个唯一的字符串。


没有名为itoa的标准函数,为什么不使用sprintf来代替

a标准函数?

最后使用指针 - 对于char类型的指针,我使用printf()和
手动逐字符打印内存块(即字符串)的内容。

尝试逐个字符打印,程序终止为GPF。我怀疑错误是在第61和第74行之间的指针操作中。

任何人都可以找到确切的错误吗?

代码如下:
1:/ *文件:006.c * /


输入这样的行号是一种痛苦,因为这意味着我不能仅仅过去
它进入文件并进行编译。

2:#include< stdio.h>
3:#include< stdlib.h>
4:#include< ; time.h>
5:
6:#define DEF_ALLOC_ITEMS 32
7:#define DEF_STR_SIZE 33 / *因为itoa()最多可以返回33个字节
* /
8:
9:int main(void)
10:{
11:char ** mptr = NULL;
12:char ** ptr = NULL;
13:char ** sptr = NULL;
14:int rnd;
15:size_t nitems = DEF_ALLOC_ITEMS;
16:size_t ctr;
17:
18:/ *分配一个指向char类型的指针数组,设置为NULL * /
19:mptr = calloc(nitems,sizeof(char *));


calloc将内存设置为所有位零,这不一定是与空指针相同的
。在任何情况下,你都不会在通过设置所有位置之前尝试阅读

,所以malloc也可以正常工作。

另外,你可以使用sizeof * mptr"而不是sizeof(char *)如果mptr

的类型发生变化,那么这个

将会是更好的风格,更容易维护。

20:if(mptr == NULL)
21:退出(EXIT_FAILURE);
22:否则
23:ptr = mptr;
24:
25:/ *播种伪 - 随机数生成器* /
26:srand((无符号)时间(NULL));
27:
28:/ *使用itoa()和rand()作为参数来获取一个字符字符串。
29:*将每个分配的指针初始化为一个块30:*已分配,零'出内存,并将其传递给itoa()。
31:*因此,我们得到一个指向char类型的指针块,每个指向
32:*一个大小为DEF_STR_SIZE的内存块,包含字符
33:*伪随机数的字符串表示。 /> 34:* /
35:nitems = DEF_STR_SIZE;
36:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)


你应该要确定你是否要使用nitems或

DEF_ALLOC_ITEMS,我个人而言将与后者一起使用。

37:{
38:* ptr = calloc(nitems,sizeof(char));


当你要立即覆盖它时,为什么还要用calloc来打扰?

39:if(* ptr == NULL)
40:退出(EXIT_FAILURE);
41:否则
42:{
43:rnd = rand();
44:printf(&!\ n生成字符串%u的随机数是:%d,
45:ctr + 1,rnd);


除非你有充分的理由不这样做,否则我认为它更好

样式在你要打印的行的末尾做\ n ,当你开始打印下一行时,而不是

。这样做意味着当你执行printf时,实际上会发生

输出,而不是坐在

行缓冲区中直到下一个printf。它还确保最后一行打印

,因为如果你没有终止,它不能保证它会被打印(或者可见,如果是打印的话,可以是
)你用\ n打印的最后一行。

46:itoa(rnd,* ptr,10);
47:}
48:ptr ++;
49:}
50:
51:/ *现在打印字符串* /
52:ptr = mptr;
53:puts(" \ n打印字符串通过printf( ):");
54:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)
55:{
56:printf(" \ nString%u is:% s",ctr + 1,* ptr);


见前面关于printf的评论。


就个人而言,我不会打扰ptr而只会使用数组

在ctr上编制索引,它减少了你必须要做的事情的数量。

57:ptr ++;
58:}
59:
60:/ *现在使用多个间接手动打印字符串... * /
61:ptr = mptr;
62:sptr = ptr;
63:puts(" \ n\\\
Printing使用多个间接手动字符串:);
64:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)
65:{
66:printf(" \ nString %u是:,ctr + 1);
67:sptr = ptr;
68:while(** sptr!=''\ 0'')
69:{
70:printf("%c",** sptr);
71:* sptr ++;


上述行是您出错​​的地方。这不符合你的想法。

72:}
73:ptr ++;
74:}
75:
76:返回0;
77:}

谢谢。
Hi all,

In the following program I allocate a block of pointers to type char,
initialised to zero. I then point each of those pointers to a block of
allocated memory of fixed size (33 bytes). A unique ''string'' is then
generated using itoa() and rand() for each block of memory.
There is no standard function called itoa, why not use sprintf which is
a standard function instead?
Finally using pointer-to-pointer of type char, I print the contents of
the blocks of memory, i.e. the strings, using both printf() and
manually, character by character.

When trying to print character by character, the program is terminated
for a GPF. I suspect the fault is in the pointer manipulations between
lines 61 and 74.

Can anyone find the exact mistake?

The code follows:
1: /* File: 006.c */
Putting in line numbers like this is a pain because it means I can''t
just past it in to a file and compile it.
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <time.h>
5:
6: #define DEF_ALLOC_ITEMS 32
7: #define DEF_STR_SIZE 33 /* Because itoa() can return upto 33 bytes
*/
8:
9: int main( void )
10: {
11: char **mptr = NULL;
12: char **ptr = NULL;
13: char **sptr = NULL;
14: int rnd;
15: size_t nitems = DEF_ALLOC_ITEMS;
16: size_t ctr;
17:
18: /* Allocate an array of pointers to type char, set to NULL */
19: mptr = calloc(nitems, sizeof (char *));
calloc sets the memory to all bits zero, this is not necessarily the
same as a null pointer. In any case, you never try to read before going
through setting up all the locations, so malloc would work just as well.
Also, you could use "sizeof *mptr" instead of "sizeof (char *)" and this
would, IMHO, be better style and easier to maintain if the type of mptr
ever changes.
20: if(mptr == NULL)
21: exit(EXIT_FAILURE);
22: else
23: ptr = mptr;
24:
25: /* Seed the pseudo-random number generator */
26: srand((unsigned) time(NULL));
27:
28: /* Use itoa() with rand() as parameter to get a character string.
29: * Initialise each of the allocated pointers to a block of
30: * allocated, zero''ed out memory, and pass it to itoa().
31: * Thus we get a block of pointers to type char, each pointing to
32: * a block of memory of size DEF_STR_SIZE, containing the character
33: * string representation of a pseudo-random number.
34: */
35: nitems = DEF_STR_SIZE;
36: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
You ought to be consistent about whether you are going to use nitems or
DEF_ALLOC_ITEMS, personally I would go with the latter.
37: {
38: *ptr = calloc(nitems, sizeof (char));
As you are going to overwrite it immediately, why bother with calloc?
39: if(*ptr == NULL)
40: exit(EXIT_FAILURE);
41: else
42: {
43: rnd = rand();
44: printf("\nGenerated random number for string %u is: %d",
45: ctr+1, rnd);
Unless you have a good reason to do otherwise I consider it far better
style to do the \n at the end of the line you are printing, instead of
when you start printing the next line. Doing this will mean that the
output actually occurs when you do the printf, instead of sitting in the
line buffer until the next printf. It also ensures the last line gets
printed, since there is no guarantee that it will be printed (or visible
if it is printed) if you don''t terminate the last line you print with a \n.
46: itoa(rnd, *ptr, 10);
47: }
48: ptr++;
49: }
50:
51: /* Now print the strings */
52: ptr = mptr;
53: puts("\nPrinting strings via printf():");
54: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
55: {
56: printf("\nString %u is: %s", ctr+1, *ptr);
See previous comments about printf.

Personally, I would not bother with ptr and would just use array
indexing on ctr, it reduces the number of things you have to get right.
57: ptr++;
58: }
59:
60: /* Now print the strings manually using multiple-indirection... */
61: ptr = mptr;
62: sptr = ptr;
63: puts("\n\nPrinting strings manually using multiple-indirection:");
64: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
65: {
66: printf("\nString %u is: ", ctr+1);
67: sptr = ptr;
68: while(**sptr != ''\0'')
69: {
70: printf("%c", **sptr);
71: *sptr++;
The above line is where you go wrong. It is not doing what you think.
72: }
73: ptr++;
74: }
75:
76: return 0;
77: }

Thanks.



-

Flash Gordon

住在有趣的时间。

虽然我的电子邮件地址说垃圾邮件,但它是真实的,我读了它。


--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.


Eric Sosman写道:
Eric Sosman wrote:
santosh写道:
santosh wrote:
[...]
当试图逐字符打印时,程序终止为GPF。我怀疑错误是在第61和第74行之间的指针操作中。

任何人都可以找到确切的错误吗?
[...]
11:char ** mptr = NULL;
12:char ** ptr = NULL;
13:char ** sptr = NULL;
[...]
60:/ *现在使用多个间接手动打印字符串... * /
61:ptr = mptr;
62:sptr = ptr ;
63:puts(使用multiple -interirection手动打印字符串:'\\ n \\ n \\ n打印字符串:");
64:for(ctr = 0; ctr< DEF_ALLOC_ITEMS; ctr ++)
65:{
66:printf(" \ nString%u is:",ctr + 1);
67:sptr = ptr;
68:while(** sptr !=''\ 0'')69:{
70:printf("%c",** sptr);
71:* sptr ++;
这个line不会做你认为的那样。
[...]
When trying to print character by character, the program is terminated
for a GPF. I suspect the fault is in the pointer manipulations between
lines 61 and 74.

Can anyone find the exact mistake?
[...]

11: char **mptr = NULL;
12: char **ptr = NULL;
13: char **sptr = NULL; [...]
60: /* Now print the strings manually using multiple-indirection... */
61: ptr = mptr;
62: sptr = ptr;
63: puts("\n\nPrinting strings manually using multiple-indirection:");
64: for(ctr = 0; ctr < DEF_ALLOC_ITEMS; ctr++)
65: {
66: printf("\nString %u is: ", ctr+1);
67: sptr = ptr;
68: while(**sptr != ''\0'')
69: {
70: printf("%c", **sptr);
71: *sptr++;
This line doesn''t do what you think it does.




谢谢。你是对的。我把优先权搞砸了。


我正在使用的这本书说如果在表达式中使用两个具有相同优先级的运算符

级别然后从左到右执行操作。

。如果是这样的话,那么上面的陈述应该有正确的工作,不应该吗?不是吗?


无论如何我把它改成了:

(* sptr)++;

它工作正常。



Thanks. You''re right. I got the precedence messed-up.

The book I''m using says that if two operators of the same precedence
level are used in an expression, then operations are performed from
left to right. If that''s so, then the above statement should have
worked correctly, shouldn''t it?

Anyway I changed it to:
(*sptr)++;
It works correctly.

72:}
73:ptr ++;
74:}
72: }
73: ptr++;
74: }



-
Eric Sosman



--
Eric Sosman


es ***** @ acm-dot-org.inva lid






这篇关于多个间接混乱......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆