鱼C论坛

 找回密码
 立即注册
查看: 422|回复: 4

[已解决]realloc

[复制链接]
发表于 2023-7-27 09:09:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        
        TCHAR* p, * q;

        //用法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)

        p = (TCHAR*)malloc(10 * sizeof(TCHAR));
        
        for (int i = 0; i < 9 * sizeof(TCHAR);i=i+ sizeof(TCHAR)) {
                *(p + i) = _T('a');

        }

        *(p + 9) = _T('\0');

        q = (TCHAR*)realloc(p, 15*sizeof(TCHAR));//修改数组容量
        /*
        格式:指针名=(数据类型*)realloc(源指针名,新的大小)
        将原数组中的数据拷贝到新的数组中,释放掉原数组,并返回一个数组首地址
        若失败:不会释放掉原数组,会返回一个空地址,表示开辟新数组失败,原来的数组空间没动

        */

        if (q != NULL) {
                for (int i = 9*sizeof(TCHAR); i < 13 * sizeof(TCHAR); i=i+ sizeof(TCHAR)) {
                        *(q + i) =_T( 'b');

                }
        }

        *(p + 14 * sizeof(TCHAR)) = _T('\0');

        CString str = q;

        ::OutputDebugString(str);



出现两个问题:1  为何有乱码?
                        2.q  没有扩容 ?




最佳答案
2023-7-27 09:57:26
1.可能是因为在使用 _T('a') 和 _T('b') 时,它们被转换成了不同的编码格式,导致输出时出现乱码。建议使用 Unicode 编码的字符,如 L'a' 和 L'b'。

2.实际上,q 已经被成功扩容了。在 realloc 函数执行成功后,q 指向了新的内存地址,而原来的内存空间已经被释放。因此,应该使用 q 指针来访问新的内存空间,而不是 p 指针。另外,最后一行代码中的 *(p + 14 * sizeof(TCHAR)) 应该改为 *(q + 14),以避免访问已经被释放的内存空间。

修改代码:
TCHAR* p, * q;

// 分配初始内存空间
p = (TCHAR*)malloc(10 * sizeof(TCHAR));

// 初始化 p 中的数据
for (int i = 0; i < 9; i++) {
    *(p + i) = _T('a');
}
*(p + 9) = _T('\0');

// 扩容 p
q = (TCHAR*)realloc(p, 15 * sizeof(TCHAR));

if (q != NULL) {
    // 在 q 中添加新的数据
    for (int i = 9; i < 13; i++) {
        *(q + i) = _T('b');
    }
    *(q + 14) = _T('\0');
}

// 使用 q 输出结果
CString str = q;
::OutputDebugString(str);

// 释放内存空间
free(q);

楼主给个最佳答案吧
11.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-27 09:10:24 | 显示全部楼层
问题1:为什么会出现乱码?

出现乱码的原因是因为在复制字符时,没有正确处理 Unicode 编码的情况。在使用 *(q + i) = _T('b'); 进行字符赋值时,应该使用 _T('b') 而不是 'b'

修正后的代码如下:
for (int i = 9 * sizeof(TCHAR); i < 13 * sizeof(TCHAR); i += sizeof(TCHAR)) {    *(q + i) = _T('b');}
问题2:为什么 q 没有扩容?

根据您提供的代码,在调用 realloc() 函数时,使用的是指针 p 进行扩容操作,而您期望的是将扩容后的地址赋值给指针 q。这里存在一个误解:realloc() 函数会尝试重新分配内存空间,并返回重新分配后的指针,但并不保证一定会在原地进行扩容,可能会返回一个新的地址。

修正代码如下:
q = (TCHAR*)realloc(p, 15 * sizeof(TCHAR));if (q != NULL) {    // 对 q 进行操作}
通过将 realloc() 的返回值赋值给指针 q,可以确保将重新分配后的地址保存在 q 中。

请注意,如果 realloc() 失败,返回的指针将为 NULL,此时应该谨慎处理,避免使用无效的指针。

总结:乱码问题是由于未正确处理 Unicode 编码的字符赋值所导致的。在使用 _T() 宏时,请确保将其用于字符赋值。另外,q 没有扩容的原因是没有将 realloc() 的返回值赋值给指针 q,需要将返回值赋给 q 才能获取重新分配后的地址。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-27 09:10:36 | 显示全部楼层
感谢您提供的代码和问题。根据您的代码,我看到了两个问题。

1. 乱码问题:
   在代码中,您将重新分配的内存地址赋值给了指针q,然后将q转换为CString类型并输出为Debug信息。但是,您可能在创建CString对象时没有正确处理字符编码。CString默认使用系统默认的字符编码,这可能会导致乱码问题。
   解决方法是使用CStringT类模板及其相关的字符集类型参数来明确指定字符编码。例如,如果您的字符集是Unicode,可以使用CStringW类来处理:
   
   CStringW str(q);
   ::OutputDebugStringW(str);
   
   
   或者,如果您的字符集是多字节字符集(如UTF-8),可以使用CStringA类来处理:
   
   CStringA str(q);
   ::OutputDebugStringA(str);
   

   选择适当的CString类取决于您的应用程序和字符集的设置。

2. q没有扩容问题:
   您在代码中使用realloc函数来改变p所指向内存的大小,并将返回的新内存地址赋值给q。然而,在使用realloc函数时,它可能会返回一个新的内存地址,也可能会在原地扩展原始内存块。因此,即使q和p不相等,q实际上可能指向了p之前指向的内存块,并且已经成功地改变了内存大小。

   但是,问题在于您在代码的最后一行尝试将终止符'\0'写入p指向的内存地址,而不是q。为了修复这个问题,您应该将 *(p + 14 * sizeof(TCHAR)) 修改为 *(q + 14 * sizeof(TCHAR)),以正确设置终止符。

修正后的代码如下所示:
realloc, TCHAR* p, * q;
p = (TCHAR*)malloc(10 * sizeof(TCHAR));

for (int i = 0; i < 9 * sizeof(TCHAR); i += sizeof(TCHAR)) {
    *(p + i) = _T('a');
}
*(p + 9) = _T('\0');

q = (TCHAR*)realloc(p, 15 * sizeof(TCHAR));

if (q != NULL) {
    for (int i = 9 * sizeof(TCHAR); i < 13 * sizeof(TCHAR); i += sizeof(TCHAR)) {
        *(q + i) = _T('b');
    }
}

*(q + 14 * sizeof(TCHAR)) = _T('\0');

CString str(q);
::OutputDebugString(str);

请尝试使用修改后的代码,并检查乱码和扩容问题是否得到解决。如果问题仍然存在,请提供更多详细信息,以便我可以更好地帮助您解决问题。另外,请确保您的工程已正确设置字符编码和相关选项。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-27 09:10:38 | 显示全部楼层
问题1:为何有乱码?

乱码的原因在于在对p指针进行内存扩容后,没有正确地将新的字符赋值给q指针。在循环中,只有从9*sizeof(TCHAR)到13*sizeof(TCHAR)的位置进行了赋值,而其他位置的字符没有被赋值,导致了乱码的出现。解决这个问题的方法是在循环中,将所有位置的字符都正确地赋值。

问题2:q没有扩容?

在代码中,对p指针进行了内存扩容,并将扩容后的指针赋值给了q指针。但是,在循环中,却仍然使用的是p指针进行赋值操作。这是因为realloc函数在扩容时,会将原数组中的数据拷贝到新的数组中,并返回一个新的数组首地址。所以,在循环中,应该使用q指针进行赋值操作,而不是p指针。解决这个问题的方法是将循环中的p指针改为q指针。

修正后的代码如下:
TCHAR* p, * q;

p = (TCHAR*)malloc(10 * sizeof(TCHAR));

for (int i = 0; i < 9 * sizeof(TCHAR); i = i + sizeof(TCHAR)) {
    *(p + i) = _T('a');
}

*(p + 9) = _T('\0');

q = (TCHAR*)realloc(p, 15 * sizeof(TCHAR));

if (q != NULL) {
    for (int i = 9 * sizeof(TCHAR); i < 14 * sizeof(TCHAR); i = i + sizeof(TCHAR)) {
        *(q + i) = _T('b');
    }
}

*(q + 14 * sizeof(TCHAR)) = _T('\0');

CString str = q;

::OutputDebugString(str);

这样修改后,乱码问题将被解决,并且q指针也会正确地进行扩容。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-27 09:57:26 | 显示全部楼层    本楼为最佳答案   
1.可能是因为在使用 _T('a') 和 _T('b') 时,它们被转换成了不同的编码格式,导致输出时出现乱码。建议使用 Unicode 编码的字符,如 L'a' 和 L'b'。

2.实际上,q 已经被成功扩容了。在 realloc 函数执行成功后,q 指向了新的内存地址,而原来的内存空间已经被释放。因此,应该使用 q 指针来访问新的内存空间,而不是 p 指针。另外,最后一行代码中的 *(p + 14 * sizeof(TCHAR)) 应该改为 *(q + 14),以避免访问已经被释放的内存空间。

修改代码:
TCHAR* p, * q;

// 分配初始内存空间
p = (TCHAR*)malloc(10 * sizeof(TCHAR));

// 初始化 p 中的数据
for (int i = 0; i < 9; i++) {
    *(p + i) = _T('a');
}
*(p + 9) = _T('\0');

// 扩容 p
q = (TCHAR*)realloc(p, 15 * sizeof(TCHAR));

if (q != NULL) {
    // 在 q 中添加新的数据
    for (int i = 9; i < 13; i++) {
        *(q + i) = _T('b');
    }
    *(q + 14) = _T('\0');
}

// 使用 q 输出结果
CString str = q;
::OutputDebugString(str);

// 释放内存空间
free(q);

楼主给个最佳答案吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 22:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表