内存映射mmap函数的类型强制转换错误---------g++和gcc编译器的不同

venusf 2014-10-22 09:30:34
写了一个测试内存映射的demo,本来mmap的返回值为(void*),代码中需要强制转换成(char*)。用gcc编译器编译的时候没有出现错误,并且运行正常。但是用g++的时候出现了invalid conversion from 'void*' to 'char*' [-fpermissive] 该错误。不知原因所在,求大神们帮忙解释一下。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
void createFile( int argc, char *argv[] );
void linuxMmap(char* filePath);
void linuxApi(char* filePath);

//运行环境为 linux

//gcc编译代码可正常运行 g++不行

//输入参数为: ./main 5000000 1.txt
//第一个参数为可执行文件 第二个参数为带生成文件的行数 第三个文件为待生成的文件名
int main(int argc, char *argv[])
{
// if(argc != 2)
{
// printf("usage:readlog log.txt");
// return 0;
}
createFile(argc,argv);
printf("\n");
printf("\n");
printf("\n");
linuxMmap(argv[2]);
printf("\n");
printf("\n");
// linuxApi(argv[1]);
}
void createFile( int argc, char *argv[] )
{
long len = atoi( argv[1] );
FILE * fd = fopen( argv[2], "w+" );
if ( fd != NULL )
{
int i = 0;
char buff[30];
struct tm *gmTime;
time_t timeTPre = time( NULL );
for ( ; i < len; i++ )
{
time_t timeT = time(NULL);
gmTime = gmtime( &timeT );
sprintf( buff, "%4d-%02d-%02d %02d:%02d:%02d %d\n",
gmTime->tm_year + 1900,
gmTime->tm_mon + 1,
gmTime->tm_mday,
gmTime->tm_hour,
gmTime->tm_min,
gmTime->tm_sec, i );
fputs( buff, fd );
};
fclose( fd );
printf( "Log: %s is finished. \nCost time %d sec\n", argv[2], (int)(time(NULL) - timeTPre ));
}
}
void linuxMmap(char* filePath)
{
char *memory = NULL;
long file_length = 0;
char *start_address = 0;
int line_num = 0;
int time_start = time(NULL);
int fd = open( filePath, O_RDONLY );
if ( fd > 0 )
{
file_length = lseek(fd, 1, SEEK_END);
memory = mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 );

long i=0;
for ( ; i<file_length; i++ )
{
if ( memory[i] == '\n' )
{
++line_num;
}
}
close( fd );
munmap( memory, file_length );
printf("Finished, total lines is %d \n", line_num);
printf("total costed time %d sec\n", (int)(time(NULL) - time_start));
}
}


...全文
493 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
venusf 2014-10-22
  • 打赏
  • 举报
回复
引用 楼主 venusf 的回复:
写了一个测试内存映射的demo,本来mmap的返回值为(void*),代码中需要强制转换成(char*)。用gcc编译器编译的时候没有出现错误,并且运行正常。但是用g++的时候出现了invalid conversion from 'void*' to 'char*' [-fpermissive] 该错误。不知原因所在,求大神们帮忙解释一下。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
void createFile( int argc, char *argv[] );
void linuxMmap(char* filePath);
void linuxApi(char* filePath);

//运行环境为   linux

//gcc编译代码可正常运行  g++不行
  
//输入参数为:  ./main  5000000 1.txt
//第一个参数为可执行文件  第二个参数为带生成文件的行数 第三个文件为待生成的文件名
int main(int argc, char *argv[])
{
       // if(argc != 2)
        {
//                printf("usage:readlog log.txt");
        //        return 0;
        }
    createFile(argc,argv);
    printf("\n");
    printf("\n");
    printf("\n");
    linuxMmap(argv[2]);
    printf("\n");
    printf("\n");
    // linuxApi(argv[1]);
}
void createFile( int argc, char *argv[] )
{
        long len = atoi( argv[1] );
        FILE * fd = fopen( argv[2], "w+" );
        if ( fd != NULL )
        {
                int i = 0;
                char buff[30];
                struct tm *gmTime;
                time_t timeTPre = time( NULL );
                for ( ; i < len; i++ )
                {
                        time_t timeT = time(NULL);
                        gmTime = gmtime( &timeT );
                        sprintf( buff, "%4d-%02d-%02d %02d:%02d:%02d %d\n",
                                                gmTime->tm_year + 1900,
                                                gmTime->tm_mon + 1,
                                                gmTime->tm_mday,
                                                gmTime->tm_hour,
                                                gmTime->tm_min,
                                                gmTime->tm_sec, i );
                        fputs( buff, fd );
                };
                fclose( fd );
                printf( "Log: %s is finished. \nCost time %d sec\n", argv[2], (int)(time(NULL) - timeTPre ));
        }
}
void linuxMmap(char* filePath)
{
	char *memory = NULL;
	long file_length = 0;
	char *start_address = 0;
	int line_num = 0;
	int time_start = time(NULL);
	int fd = open( filePath, O_RDONLY );
	if ( fd > 0 )
    {
		file_length = lseek(fd, 1, SEEK_END);
		memory = mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 );

		long i=0;
		for ( ; i<file_length; i++ )
		{
			if ( memory[i] == '\n' )
			{
				++line_num;
			}
		}
		close( fd );
		munmap( memory, file_length );
		printf("Finished, total lines is %d \n", line_num);
		printf("total costed time %d sec\n", (int)(time(NULL) - time_start));
	}
}


嗯嗯,没有考虑到这方面,以为void*转换成char*是可以的,没想到void*不行。
venusf 2014-10-22
  • 打赏
  • 举报
回复
引用 2 楼 lovesmiles 的回复:
memory = static_cast<char*>mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 ); 加一个强制转换。
确实如此,本来我只是在mmap前面加一个(char*)但是不行。加上static_cast<char*>后是这样的,需要加上一个括号 memory = static_cast<char*>(mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 ));
帅得不敢出门 2014-10-22
  • 打赏
  • 举报
回复
c++相对c来说是强类型的
勤奋的小游侠 2014-10-22
  • 打赏
  • 举报
回复
memory = static_cast<char*>mmap( start_address, file_length, PROT_READ, MAP_SHARED, fd, 0 ); 加一个强制转换。
JiangWenjie2014 2014-10-22
  • 打赏
  • 举报
回复
是这样的,C指针的赋值是不用考虑类型的。但是C++不同类型的指针默认是不允许赋值的(除了子类指针能够自动转换为基类指针,还有特殊的void*指针),所以需要显式地转换一下,static_cast,dynamic_cast等等是C++特有的为指针转换而提供的。

65,193

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧