使用 malloc 定义字符串地址

Use malloc to define a string address

提问人:ben 提问时间:10/15/2023 最后编辑:John Kugelmanben 更新时间:10/15/2023 访问量:63

问:

当我运行此代码时,我没有得到任何输出。我希望使用大写值写入文件,并将大写值打印到屏幕上。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int main(int argc, const char * argv[]) {
    
    FILE *fP;
    
    char *str = "this is an example";
    /* Im not sure if this line is right */
    str = (char *)malloc(sizeof(char) * 100);
    
    fopen("4.txt", "w");

    size_t length = strlen(str);

    for (size_t i = 0; i < length; i++)
    {
        /* This line fails */
        fprintf(fP, "%c", toupper(*(str +i )));
        printf("%c", toupper(*(str +i )));
    }
    
    return 0;
}
C 文件 malloc

评论

0赞 Fe2O3 10/15/2023
尝试:。。。而且,您应该检查 AND,不要忘记何时完成使用它......PS:此代码中不需要...事实上,重新分配指针以取消初始化内存会以眼泪告终......fP = fopen("4.txt", "w");if( fP == NULL ) /* error and exit */fclose( fP );malloc()str
0赞 nicomp 10/15/2023
正如我之前评论的那样,请阅读警告。任何像样的现代编译器都应该告诉你 fP 没有初始化。
0赞 stark 10/15/2023
如果您尝试将 str 转换为 100 字节数组,则只需将其声明为 100 字节数组即可。

答:

4赞 user17231236 10/15/2023 #1

您正在运行 fopen() 而没有返回 fp,这只会打开文件流,但不会让它被 fp 引用,您需要将该行更改为

fp = fopen("4.txt" , "w");

通过检查 fp 是否存储 NULL 地址来检查 fopen 是否失败

if(!fp){
   printf("fopen() failed");
   return -1;
}

此外,您在 str 上运行 strlen(),但由于您分配的内存没有在其中存储任何内容(之前分配的字符串被覆盖,因为您向 str 写入了一个新值,该值是 malloc 返回的地址)它将返回一个随机数(malloc() 给出一个内存块,而不清除之前存在的内容, 因此,无论之前使用它的程序放在哪里,都将存储在其中) 你需要像这样使用 strcpy() 将字符串设置到其中

strcpy(str , "this is an example");

此外,使用完指针后,您需要使用 free() 释放指针。

free(str);

ALWAYS 释放由 malloc() 和 calloc() 给出的内存。

如果解决了这些问题,它应该会运行。

其他需要注意的一点是,main() 似乎不使用命令行参数,因此

(int argc, const char* argv[])

在此特定示例代码中是不必要的。

此外,使用

(*(str+i))

可能有点难以阅读,相反,我建议使用

str[i]

它在功能上的作用相同,但更容易阅读

评论

3赞 Jonathan Leffler 10/15/2023
你说“之前分配的字符串被覆盖了......”——不是真的:输入的指针被更改为 返回的值,但字符串没有被修改。strmalloc()"this is an example"
2赞 Jonathan Leffler 10/15/2023
请重做我所做的更改以添加大写字母和其他更改。尝试阅读没有句子开头等指示符的文本是令人沮丧的。修复问题却看到修复被覆盖也是令人沮丧的。在英语中,逗号前没有空格——请不要添加它们。逗号后面的空格 — 是的;前面的空格 — 否。
0赞 user17231236 10/15/2023
@JonathanLeffler 对于不小心撤消您的编辑,我深表歉意。我有点急于添加更多关于正确记忆管理的部分,我没有意识到其他人正在改进答案的语法。
0赞 ad absurdum 10/15/2023
“之前分配的字符串被覆盖”不准确。 是一个指针,首先它的值是一些存储的地址,其中包含从 .赋值后的结果不再持有此地址,也就是说原始存储的地址丢失了。也就是说,字符串不会被覆盖,指针值会被覆盖。这对于字符串文字无关紧要,因为它们具有静态存储持续时间。但这确实很重要:如果初始分配是动态的,这将是内存泄漏。str"this is an example"mallocstr
1赞 Jonathan Leffler 10/15/2023
@user17231236:更糟糕的事情发生了,这并不罕见,尤其是在答案发布后的最初几分钟。但密切关注是否有其他人编辑了您的答案也是一个好主意。感谢您重做修复。另外:请记住,如果您不同意编辑,您可以自由撤消它。