调用realloc函数后除了第一个其他全部变为野指针

作者:超级管理员 更新时间:2017-10-31 15:59:00 来源:未知 点击:15642
#include #define QUEUE_INIT_SIZE 4#define QUEUE_ADD 10typedef struct {int *rear;int *front
#include <iostream>
#define QUEUE_INIT_SIZE 4
#define QUEUE_ADD 10
typedef struct {
int *rear;
int *front;
int queuesize;
}SqQueue;
void InitQueue(SqQueue &s) {
s.front = (int *)malloc(sizeof(int));
if (!s.rear) exit(0);
s.rear = s.front;
s.queuesize = QUEUE_INIT_SIZE;
}
void EnQueue(SqQueue &s, int e) {
if (s.rear - s.front >= s.queuesize)
{
int *ptr = (int *)realloc(s.front, (s.queuesize + QUEUE_ADD) * (sizeof(int)));
if (!ptr) exit(0);
s.front = ptr;
/*printf("%d\n", *(s.front ));
printf("%d\n", *(s.front+1));
printf("%d\n", *(s.front + 1+1));*/
s.rear = s.front + s.queuesize;
s.queuesize += QUEUE_ADD;
printf("申请空间成功\n");
}
*s.rear = e;
s.rear++;
printf("元素%d已入队列\n", e);
}
void DeQueue(SqQueue &s) {
if (s.front == s.rear)
{
printf("队列为空\n");
exit(0);
}
int e = *(s.front);
s.front++;
printf("元素%d已出队列\n", e);
}
int main() {
SqQueue s;
InitQueue(s);
EnQueue(s, 1);
EnQueue(s, 2);
EnQueue(s, 3);
EnQueue(s, 4);
EnQueue(s, 5);
DeQueue(s);
DeQueue(s);
DeQueue(s);
return 0;
}



在使用realloc之后除了第一个s.front,其他的都变成了野指针
求解,谢谢。

realloc
Reallocate memory blocks.

void *realloc( void *memblock, size_t size );

Routine Required Header Compatibility 
realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT 


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 


Return Value

realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

Parameters

memblock

Pointer to previously allocated memory block

size

New size in bytes

Remarks

The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.

The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.

realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call 

_set_new_mode(1)

early in your program, or link with NEWMODE.OBJ.

When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.

Example

/* REALLOC.C: This program allocates a block of memory for
 * buffer and then uses _msize to display the size of that
 * block. Next, it uses realloc to expand the amount of
 * memory used by buffer and then calls _msize again to
 * display the new amount of memory allocated to buffer.
 */

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

void main( void )
{
   long *buffer;
   size_t size;

   if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )
      exit( 1 );

   size = _msize( buffer );
   printf( "Size of block after malloc of 1000 longs: %u\n", size );

   /* Reallocate and show new size: */
   if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) )) 
        ==  NULL )
      exit( 1 );
   size = _msize( buffer );
   printf( "Size of block after realloc of 1000 more longs: %u\n", 
            size );

   free( buffer );
   exit( 0 );
}


Output

Size of block after malloc of 1000 longs: 4000
Size of block after realloc of 1000 more longs: 8000


Memory Allocation Routines

See Also   calloc, free, malloc

#include <iostream>
#include <cstdio>
#include <cstdlib>

#define QUEUE_INIT_SIZE 4
#define QUEUE_ADD 10

typedef struct {
    int *rear;
    int *front;
    int queuesize;
}SqQueue;

void InitQueue(SqQueue &s)
{
    s.front = (int *)malloc(sizeof(int));
    if (!s.rear)
        exit(0);
    s.rear = s.front;
    s.queuesize = QUEUE_INIT_SIZE;
}
void EnQueue(SqQueue &s, int e)
{
    if (s.rear - s.front >= s.queuesize) {
        int *ptr = (int *)realloc(s.front, (s.queuesize + QUEUE_ADD) * (sizeof(int)));
        if (!ptr)
            exit(0);
        s.front = ptr;
#if 0
        printf("%d\n", *(s.front ));
          printf("%d\n", *(s.front+1));
          printf("%d\n", *(s.front + 1+1));
#endif
        //s.rear = s.front + s.queuesize;    /*不需要修改s.rear的位置*/
        s.queuesize += QUEUE_ADD;
        printf("申请空间成功\n");
    }
    *s.rear = e;
    s.rear++;
    printf("元素%d已入队列\n", e);
}
void DeQueue(SqQueue &s) {
    if (s.front == s.rear)
    {
        printf("队列为空\n");
        exit(0);
    }
    int e = *(s.front);
    s.front++;
    printf("元素%d已出队列\n", e);
}
int main() {
    SqQueue s;
    InitQueue(s);
    EnQueue(s, 1);
    EnQueue(s, 2);
    EnQueue(s, 3);
    EnQueue(s, 4);
    EnQueue(s, 5);
    DeQueue(s);
    DeQueue(s);
    DeQueue(s);
    return 0;
}

当队列满时,不需要修改s.rear的位置,因为s.rear的位置只会在入队的时候修改;
realloc后不会出现野指针的问题。

realloc后修改s.rear的位置,反而会导致再次入队时缓存越界

引用 2 楼 cfjtaishan 的回复:
#include <iostream>
#include <cstdio>
#include <cstdlib>

#define QUEUE_INIT_SIZE 4
#define QUEUE_ADD 10

typedef struct {
    int *rear;
    int *front;
    int queuesize;
}SqQueue;

void InitQueue(SqQueue &s)
{
    s.front = (int *)malloc(sizeof(int));
    if (!s.rear)
        exit(0);
    s.rear = s.front;
    s.queuesize = QUEUE_INIT_SIZE;
}
void EnQueue(SqQueue &s, int e)
{
    if (s.rear - s.front >= s.queuesize) {
        int *ptr = (int *)realloc(s.front, (s.queuesize + QUEUE_ADD) * (sizeof(int)));
        if (!ptr)
            exit(0);
        s.front = ptr;
#if 0
        printf("%d\n", *(s.front ));
          printf("%d\n", *(s.front+1));
          printf("%d\n", *(s.front + 1+1));
#endif
        //s.rear = s.front + s.queuesize;    /*不需要修改s.rear的位置*/
        s.queuesize += QUEUE_ADD;
        printf("申请空间成功\n");
    }
    *s.rear = e;
    s.rear++;
    printf("元素%d已入队列\n", e);
}
void DeQueue(SqQueue &s) {
    if (s.front == s.rear)
    {
        printf("队列为空\n");
        exit(0);
    }
    int e = *(s.front);
    s.front++;
    printf("元素%d已出队列\n", e);
}
int main() {
    SqQueue s;
    InitQueue(s);
    EnQueue(s, 1);
    EnQueue(s, 2);
    EnQueue(s, 3);
    EnQueue(s, 4);
    EnQueue(s, 5);
    DeQueue(s);
    DeQueue(s);
    DeQueue(s);
    return 0;
}

当队列满时,不需要修改s.rear的位置,因为s.rear的位置只会在入队的时候修改;
realloc后不会出现野指针的问题。


这是您修改后代码的运行截图,还是会出现野指针问题,还有就是我觉得应该需要修改s.rear的地址,因为s.front已经指向了新地址,如果s.rear不修改的话,新入队的元素就无法通过s.front++来出队。
如有不正确的地方,请您指正。

引用 1 楼 zhao4zhong1 的回复:
realloc
Reallocate memory blocks.

void *realloc( void *memblock, size_t size );

Routine Required Header Compatibility 
realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT 


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 


Return Value

realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

Parameters

memblock

Pointer to previously allocated memory block

size

New size in bytes

Remarks

The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.

The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.

realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call 

_set_new_mode(1)

early in your program, or link with NEWMODE.OBJ.

When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.

Example

/* REALLOC.C: This program allocates a block of memory for
 * buffer and then uses _msize to display the size of that
 * block. Next, it uses realloc to expand the amount of
 * memory used by buffer and then calls _msize again to
 * display the new amount of memory allocated to buffer.
 */

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

void main( void )
{
   long *buffer;
   size_t size;

   if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )
      exit( 1 );

   size = _msize( buffer );
   printf( "Size of block after malloc of 1000 longs: %u\n", size );

   /* Reallocate and show new size: */
   if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) )) 
        ==  NULL )
      exit( 1 );
   size = _msize( buffer );
   printf( "Size of block after realloc of 1000 more longs: %u\n", 
            size );

   free( buffer );
   exit( 0 );
}


Output

Size of block after malloc of 1000 longs: 4000
Size of block after realloc of 1000 more longs: 8000


Memory Allocation Routines

See Also   calloc, free, malloc

感谢您的回答,但是我看realloc的说明上会引起数据丢失的只有新申请的空间比原来小的情况,不太明白为什么我的代码还是会造成数据丢失。

引用 4 楼 to__be 的回复:
Quote: 引用 2 楼 cfjtaishan 的回复:

#include <iostream>
#include <cstdio>
#include <cstdlib>

#define QUEUE_INIT_SIZE 4
#define QUEUE_ADD 10

typedef struct {
    int *rear;
    int *front;
    int queuesize;
}SqQueue;

void InitQueue(SqQueue &s)
{
    s.front = (int *)malloc(sizeof(int));
    if (!s.rear)
        exit(0);
    s.rear = s.front;
    s.queuesize = QUEUE_INIT_SIZE;
}
void EnQueue(SqQueue &s, int e)
{
    if (s.rear - s.front >= s.queuesize) {
        int *ptr = (int *)realloc(s.front, (s.queuesize + QUEUE_ADD) * (sizeof(int)));
        if (!ptr)
            exit(0);
        s.front = ptr;
#if 0
        printf("%d\n", *(s.front ));
          printf("%d\n", *(s.front+1));
          printf("%d\n", *(s.front + 1+1));
#endif
        //s.rear = s.front + s.queuesize;    /*不需要修改s.rear的位置*/
        s.queuesize += QUEUE_ADD;
        printf("申请空间成功\n");
    }
    *s.rear = e;
    s.rear++;
    printf("元素%d已入队列\n", e);
}
void DeQueue(SqQueue &s) {
    if (s.front == s.rear)
    {
        printf("队列为空\n");
        exit(0);
    }
    int e = *(s.front);
    s.front++;
    printf("元素%d已出队列\n", e);
}
int main() {
    SqQueue s;
    InitQueue(s);
    EnQueue(s, 1);
    EnQueue(s, 2);
    EnQueue(s, 3);
    EnQueue(s, 4);
    EnQueue(s, 5);
    DeQueue(s);
    DeQueue(s);
    DeQueue(s);
    return 0;
}

当队列满时,不需要修改s.rear的位置,因为s.rear的位置只会在入队的时候修改;
realloc后不会出现野指针的问题。


这是您修改后代码的运行截图,还是会出现野指针问题,还有就是我觉得应该需要修改s.rear的地址,因为s.front已经指向了新地址,如果s.rear不修改的话,新入队的元素就无法通过s.front++来出队。
如有不正确的地方,请您指正。

没看出有啥问题,在我的PC上测试都是正常的。

#include <iostream>
#include <cstdio>
#include <cstdlib>

#define QUEUE_INIT_SIZE 4
#define QUEUE_ADD 10

typedef struct {
    int *rear;
    int *front;
    int *orig;
    int queuesize;
}SqQueue;

void InitQueue(SqQueue &s)
{
    s.orig = (int *)malloc(QUEUE_INIT_SIZE * sizeof(int));
    if (!s.orig)
        exit(0);
    s.rear = s.front = s.orig;
    s.queuesize = QUEUE_INIT_SIZE;
}
void EnQueue(SqQueue &s, int e)
{
    if (s.rear - s.orig >= s.queuesize) {
        int *ptr = (int *)realloc(s.orig, (s.queuesize + QUEUE_ADD) * (sizeof(int)));
        if (!ptr)
            exit(0);
        s.orig = ptr;
        s.queuesize += QUEUE_ADD;
        printf("申请空间成功\n");
    }
    *s.rear = e;
    s.rear++;
    printf("元素%d已入队列\n", e);
}
void DeQueue(SqQueue &s) {
    if (s.front == s.rear)
    {
        printf("队列为空\n");
        return;
    }
    int e = *(s.front);
    s.front++;
    printf("元素%d已出队列\n", e);
}
int main() {
    SqQueue s;
    InitQueue(s);
    EnQueue(s, 1);
    EnQueue(s, 2);
    EnQueue(s, 3);
    EnQueue(s, 4);
    EnQueue(s, 5);
    DeQueue(s);
    DeQueue(s);
    DeQueue(s);
    free(s.orig);
    return 0;
}
//元素1已入队列
//元素2已入队列
//元素3已入队列
//元素4已入队列
//申请空间成功
//元素5已入队列
//元素1已出队列
//元素2已出队列
//元素3已出队列
//

引用 5 楼 to__be 的回复:
Quote: 引用 1 楼 zhao4zhong1 的回复:

realloc
Reallocate memory blocks.

void *realloc( void *memblock, size_t size );

Routine Required Header Compatibility 
realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT 


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 


Return Value

realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

Parameters

memblock

Pointer to previously allocated memory block

size

New size in bytes

Remarks

The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.

The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.

realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call 

_set_new_mode(1)

early in your program, or link with NEWMODE.OBJ.

When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.

Example

/* REALLOC.C: This program allocates a block of memory for
 * buffer and then uses _msize to display the size of that
 * block. Next, it uses realloc to expand the amount of
 * memory used by buffer and then calls _msize again to
 * display the new amount of memory allocated to buffer.
 */

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

void main( void )
{
   long *buffer;
   size_t size;

   if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )
      exit( 1 );

   size = _msize( buffer );
   printf( "Size of block after malloc of 1000 longs: %u\n", size );

   /* Reallocate and show new size: */
   if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) )) 
        ==  NULL )
      exit( 1 );
   size = _msize( buffer );
   printf( "Size of block after realloc of 1000 more longs: %u\n", 
            size );

   free( buffer );
   exit( 0 );
}


Output

Size of block after malloc of 1000 longs: 4000
Size of block after realloc of 1000 more longs: 8000


Memory Allocation Routines

See Also   calloc, free, malloc

感谢您的回答,但是我看realloc的说明上会引起数据丢失的只有新申请的空间比原来小的情况,不太明白为什么我的代码还是会造成数据丢失。

你的init函数 里 s.front = (int *)malloc(sizeof(int));只分配了1个int长度,但是后面你却对4个int长度的内存有操作,你破坏了堆结构,再realloc,则出错
建议init里面malloc(sizeof(int)*4);

如果当前内存不够分配,realloc会重新寻找其他位置内存,并将数据移动过去,导致原来的一些指针失效

http://en.cppreference.com/w/c/memory/realloc

谢谢大家..问题基本解决

推荐阅读

热门内容

VS2010新建IT++工程时报错,求指

修复或重装VS2010没用,2013也试...

调用realloc函数后除了第一个其他全

#include #...

往byte数组拷贝二进制图像数据之后,数

运行到拷贝数据这段时这是读到的图像代码大...

C语言问题求助 求知道这种方式的人给解释

说清楚点吧  我这是常用算法程序集(C/...

已知两条直线和鼠标所在点,求经过鼠标所在

计算公式是有的,但是不同与我们手动计算用...

位数组问题 c和指针第5章第4道题

题目要求主函数是自定义的有两个问题:第一...

用Qt graphics view实现许

这个效果不错,关注。...

无GPU下win764+vs2013安装

在编译build_cpu_only中的M...

cppcms-1.0.5 windows

本帖最后由lovton于2017-10-...

vs2015 字体 不能加粗 什么原因呢

设置了  粗体  可是根本没任何效果这是...

最新内容

VS2010新建IT++工程时报错,求指教

修复或重装VS2010没用,2013也试过了,还是这个问题vs很恶心,不会配置,...

调用realloc函数后除了第一个其他全部变为野指针

#include #define QUEUE_INIT_SI...

如何在service中动态申请权限

 android6.0版本有的权限需要运行时申请,我新建的一个service,需...

经验分享 | 技术面试备忘录,饭可以乱吃,话不能乱说!

  这是关于技术面试要做和不要做的一个列表,主要用于算法面试。其中一些可能只适用...

搭建MySQL高可用负载均衡集群

软件大小:1.28MB资源类型:不详授权方式:免费/开源资料   主要内容:  ...

刘涛为安全感代言 金立M7成职场进阶之选

    近日“中年危机”这一话题热度持续走高,30岁焦虑越来越多的出现在大家的日...

全面屏千元双摄 荣耀畅玩7X明日开售

    明天(11月1日)上午10:08,荣耀在10月刚刚发布的首款全面屏手机荣...

往byte数组拷贝二进制图像数据之后,数据出现问题,大神帮忙看一看

运行到拷贝数据这段时这是读到的图像代码大神帮忙分析分析  瞅瞅~学会使用数据断点...

锤子全面屏新机曝光 坐等老罗的回复

    中关村在线消息:昨天,锤子官方正式宣布新品发布的消息——11月7日19:...

求大神解答

同样的printf语句,中间什么也没做,最后输出结果大不一样。代码如下#incl...

让安全如影随形 金立M7安全芯片打败焦虑

    10月30日,微博上出现了一个关于“焦虑”的微电影,传播十分迅速,片中内...

新中产走向30岁式焦虑 金立M7用"芯"陪伴

    随着我国人均收入水平的持续提高,新中产阶级的队伍也日益壮大,在这其中,已...

一加创始人国外晒一加5T样张 不怕暗光

    中关村在线消息:继一加5T海报和上半身清晰照曝光后,今天一加创始人Car...

18:9全面屏已无悬念 一加5T就长这样了

    中关村在线消息:下月,一加5T就发布了。继上周外媒曝光一组一加5T的海报...

如何避免网站关键词相互SEO竞争

在SEO诊断过程中遇到过很多SEOER喜欢用多个页面来优化相同的关键词,比如一位...

快看!听说Android有四大法宝!

  哈喽,艾瑞巴蒂,小编又在一个新的周二和大家见面了,古代有四大发明术:造纸术、...

vs2015+CMake+mingw编译linphone配置出错,不知道这个XercesC库怎么搞,自己

--- 已启动全部重新生成: 项目: EP_libxsd, 配置: Debug ...

实验排队功能实现(JAVA)

  pre-reade//将模块暴露出去  }  而对于com.hujian.e...

让 Python 更加充分的使用 Sqlite3

  我最近在涉及大量数据处理的项目中频繁使用sqlite3。我最初的尝试根本不涉...

PHP实现网站访问量计数器

简单的网站访问量计数器实现,具体如下首先说明思路:1.用户向服务器发出访问请求2...